javascriptruby-on-railsecmascript-6multipartform-datareact-dropzone

Uploading multiple files with Fetch and FormData APIs


I'm trying to use the native Fetch and FormData APIs to upload multiple files at once to the server but I can't for the life of me get it to work. Here's what I've got:

// acceptedFiles are File objects coming from `react-dropzone`.
function handleSubmit(acceptedFiles) {
  const data = new FormData();

  for (const file of acceptedFiles) {
    data.append('files', file, file.name);
  }

  return fetch('https://example.com/api/upload', {
    method: 'POST',
    body: data,      
  });
}

But what my Rails server receives is this:

Parameters: {"files"=>#
<ActionDispatch::Http::UploadedFile:0x00007feb347becc0 @tempfile=#
<Tempfile:/var/folders/kl/y1jrp7zs55sbx075jjjl3p280000gn/T/RackMultipart201
71112-6486-1ftkufy.mp4>, @original_filename="SampleVideo_1280x720_5mb.mp4",
 @content_type="video/mp4", @headers="Content-Disposition: form-data; 
name=\"files\"; filename=\"SampleVideo_1280x720_5mb.mp4\"\r\nContent-Type:
 video/mp4\r\n">}

In other words, it looks like files is actually just one file. But the docs for FormData say that append should append multiple files.

So what's going wrong?


Solution

  • The solution was to change files to files[]:

    // acceptedFiles are File objects coming from `react-dropzone`.
    function handleSubmit(acceptedFiles) {
      const data = new FormData();
    
      for (const file of acceptedFiles) {
        data.append('files[]', file, file.name);
      }
    
      return fetch('https://example.com/api/upload', {
        method: 'POST',
        body: data,      
      });
    }