Sails: req.body blank with multipart

Created on 23 Dec 2014  路  22Comments  路  Source: balderdashy/sails

I feel like this is beating a dead horse. I'm aware of the guidelines with Skipper and the order of the form fields. I'm still having req.body come up empty randomly as I execute the same operation over and over even though I've placed the file at the end.

Node 0.10.32
Sails 0.10.4

Output

console.log(req.body);
console.log(req.body.pages);

Sometimes:
{ mail_item_id: '19', pages: '12' }
12

Other times:
{}
undefined

HTML

<form action="/striker/mail/scan_upload" method="post" enctype="multipart/form-data">
    <input type="hidden" name="mail_item_id" value="19" />
    <div class="form-group">
        <button type="submit">Upload</button>
    </div>
    <div class="form-group">
        <input type="text" name="pages" />
    </div>
    <div class="form-group">
        <input type="file" name="uploaded_scan" />
    </div>
</form>

Chrome Console

------WebKitFormBoundaryJ2rPwyZ1CvwvvCli
Content-Disposition: form-data; name="mail_item_id"

19
------WebKitFormBoundaryJ2rPwyZ1CvwvvCli
Content-Disposition: form-data; name="pages"

12
------WebKitFormBoundaryJ2rPwyZ1CvwvvCli
Content-Disposition: form-data; name="uploaded_scan"; filename="2014-12-07-scan.pdf"
Content-Type: application/pdf

------WebKitFormBoundaryJ2rPwyZ1CvwvvCli--

Any help is appreciated.

Most helpful comment

I ran into this issue recently as well and was surprised to see it called out in the documentation: "It is important to realize that the benefit above relies on a crucial, simplifying assumption: that user agents send any text parameters before the first file parameter in the multipart HTTP request body." Never would have thought.....

All 22 comments

I suppose that you've tried that but... Have you put the submit button at the bottom of the form? Maybe is a stupid answer but if the order matters...

I've an example of skipper and a form with text and file fields that works fine, maybe it can help skipper-demo

Btw, I think that this two issues are related: https://github.com/balderdashy/sails/issues/2497

Moving the upload button to the bottom had no effect. I have file uploads working fine, it's passing additional data along with the file upload is the issue. I _could_ work around this by just using URL parameters, but, I'd really rather not.

+1 I am actually seeing anything after a file input is blank in my forms. oddly enough its only part of the time.

Guys, what version of skipper are we talking about here? Would you please try this with a fresh install of Sails v0.11? This will give you the latest fixes from Skipper.

@mikermcneil I'm going to upgrade and test this right now.

Naturally, now I can't reproduce it, even under the stated version above and certainly not with the upgraded version of Sails. Until I can consistently reproduce this, I'm going to close it out.

@mikermcneil I'm on:

sails 0.10.5
skipper 0.5.5

I moved my file input to the bottom of my form and all works fine. req.body will get anything above the file inputs.

I haven't been able to update to 0.11 yet. last time I did I was getting lots of errors.

I upgraded to 0.11 and its the same thing. fyi.

probably best to leave open.

URL : http://localhost:1337/.....

Req Header : Content-Type: multipart/form-data; boundary=----WebKitFormBoundary8SIBKjSWvg4nOGA2

Req Data :
------WebKitFormBoundary8SIBKjSWvg4nOGA2
Content-Disposition: form-data; name="filenames"

03ce4429-6e35-44ac-94be-b28098ee87d1.jpg
------WebKitFormBoundary8SIBKjSWvg4nOGA2
Content-Disposition: form-data; name="title"

sample1
------WebKitFormBoundary8SIBKjSWvg4nOGA2
Content-Disposition: form-data; name="groupId"

552f98b383d696f41078dc07
------WebKitFormBoundary8SIBKjSWvg4nOGA2
Content-Disposition: form-data; name="groupName"

All
------WebKitFormBoundary8SIBKjSWvg4nOGA2
Content-Disposition: form-data; name="type"

Photo
------WebKitFormBoundary8SIBKjSWvg4nOGA2
Content-Disposition: form-data; name="file[0]"; filename="03ce4429-6e35-44ac-94be-b28098ee87d1.jpg"
Content-Type: image/jpeg

------WebKitFormBoundary8SIBKjSWvg4nOGA2--

Hi All,

File upload working file with html form.

I am using above data with Advance rest client extension of google chrome which is same request data as html form. But it gives me blank request body object. I also tried after removing file parameter from above request data and it gives me same blank request body object.
console.log(req.body);//Gives blank json "{}"

I am using below npm modules
"rc": "~0.5.0",
"sails": "~0.11.0",
"sails-disk": "~0.10.0",
"skipper": "^0.5.5",
"skipper-gridfs": "^0.5.3"

Any help would be appreciated.

Thanks

I think this should be re-opened, getting the same issue.

I have documented more information on a ticket with skipper here. I believe its an SSL issue directly in Chrome.

@corbanb Nevermind. I was using the DropzoneJS library. The issues I had were some incompatibilities with Skipper and DropzoneJS. All fixed now.

I was had same problem, when try to upload files more then ~15Kb - file success uploaded, but req.body - empty.
Solution absolutely idiotic: on client side change .append part ordering.
From

  var payload = new FormData();
  payload.append('file', item.file);
  payload.append('foo', JSON.stringify(item.foo));
  payload.append('priority', item.priority);

to

  payload.append('foo', JSON.stringify(item.foo));
  payload.append('priority', item.priority);
  payload.append('file', item.file);

e.g. change order for multipart parts and set uploaded file as last part.

Was having the same problem... @Kyr 's answer actually worked. I would have not believe it If I didn't try myself.

I ran into this issue recently as well and was surprised to see it called out in the documentation: "It is important to realize that the benefit above relies on a crucial, simplifying assumption: that user agents send any text parameters before the first file parameter in the multipart HTTP request body." Never would have thought.....

Just be sure that file parameter is the last parameter in the request. @yellowandy is right.

i was having the same issue and wasted 5hrs just to understand whts the prblm now i got it.

seems upload function of "sails" is not stable. Every time I want to upload multiple file, I must put the file field in the bottom.

This is still an issue and @trungducng 's solution works for me as a workaround.

@trungducng 's advice worked for me. Simply send the file last. I'm using npm/request library to send requests to Sails API.

What didn't work:

formData: {
  file: fs.createReadStream(tmpFilePath),
   // ... other fields
}

What works fine:

formData: {              
  // ... other fields
  file: fs.createReadStream(tmpFilePath),
}

It's not a bug. The explanation from offical Sails documentation:

Regardless of what you're using on the client side, you'll need to do things a little differently than usual in your Sails action on the back end. Because we're dealing with a multipart upload, any text parameters in your request body must be sent before any files. This allows Sails to run your action code while files are still uploading, rather than having to wait for them to finish (avoiding a famous DDoS vulnerability in Express-based Node.js apps). See the Skipper docs for advanced information on how this works behind the scenes.

@grantbi @travispwingo

https://sailsjs.com/documentation/concepts/file-uploads

Was this page helpful?
0 / 5 - 0 ratings