inertiajs / inertia

Inertia.js lets you quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers.
https://inertiajs.com
MIT License
6.02k stars 405 forks source link

Introduce `formDataArrayFormat` option #1901

Open skryukov opened 2 weeks ago

skryukov commented 2 weeks ago

This PR adds a new formDataArrayFormat option to Link and router.visit that duplicates the logic of queryStringArrayFormat, but for formData arrays serialization.

Rationale

Currently, multipart form data arrays are always serialized using indices:

------WebKitFormBoundarynVnO6UtO8ts1Qa5q
Content-Disposition: form-data; name="model[files][0]"; filename="aliens.png"
Content-Type: image/png

------WebKitFormBoundarynVnO6UtO8ts1Qa5q
Content-Disposition: form-data; name="model[files][1]"; filename="ufo.jpg"
Content-Type: image/jpeg

Rails (or more precisely Rack) parses this as hashes with keys '0' and '1'. To support scenarios like a file input with the multiple attribute, we need to allow the tweaking of this behavior.

This PR introduces the formDataArrayFormat option to router.visit. With this option set to 'brackets', we serialize the keys in the format required by Rack/Rails:

  form.post(`/models`, {
    formDataArrayFormat: 'brackets',
  })
------WebKitFormBoundaryxrZa60F5B7gxV5aG
Content-Disposition: form-data; name="model[files][]"; filename="aliens.png"
Content-Type: image/png

------WebKitFormBoundaryxrZa60F5B7gxV5aG
Content-Disposition: form-data; name="model[files][]"; filename="ufo.jpg"
Content-Type: image/jpeg

Notes

I have set formDataArrayFormat to 'indices' by default to preserve the current behavior. We might want to synchronize formDataArrayFormat and queryStringArrayFormat values at some point (or even introduce more general option), but this could be a breaking change.