admin管理员组

文章数量:1356375

I would like to upload multiple files using a post request of type multipart/form-data and for each file I need to know the file size (content-length) on the server side.

To construct the POST request in javascript I use a FormData object and append the File objects for the upload to it. This works fine, but only a Content-type header is added to each part, in addition to the Content-Disposition header, but no Content-length header, though this information is available from the individual File objects.

Is there a way to achieve that that Content-length headers are set for every part from the FormData object when sending the request?

Below is the code I use, including my work-around to the problem. It actually uses angular-js to send the request, but I think this is not relevant to the question.

var form = new window.FormData();

form.append('additional-field-1', new Blob(['some plain text'], {type : 'text/plain'}));

for (var file in fileList) {
    var fileObj = fileList[file];
    var count = 1 + parseInt(file, null);
    form.append('file-size-' + count, new Blob([fileObj.size], {type : 'text/plain'}));
    form.append('file-' + count, fileObj);
}

$http.post(url, form, {
    transformRequest: angular.identity,
    headers: {'Content-Type': undefined}
}).success(.....

I would like to upload multiple files using a post request of type multipart/form-data and for each file I need to know the file size (content-length) on the server side.

To construct the POST request in javascript I use a FormData object and append the File objects for the upload to it. This works fine, but only a Content-type header is added to each part, in addition to the Content-Disposition header, but no Content-length header, though this information is available from the individual File objects.

Is there a way to achieve that that Content-length headers are set for every part from the FormData object when sending the request?

Below is the code I use, including my work-around to the problem. It actually uses angular-js to send the request, but I think this is not relevant to the question.

var form = new window.FormData();

form.append('additional-field-1', new Blob(['some plain text'], {type : 'text/plain'}));

for (var file in fileList) {
    var fileObj = fileList[file];
    var count = 1 + parseInt(file, null);
    form.append('file-size-' + count, new Blob([fileObj.size], {type : 'text/plain'}));
    form.append('file-' + count, fileObj);
}

$http.post(url, form, {
    transformRequest: angular.identity,
    headers: {'Content-Type': undefined}
}).success(.....
Share Improve this question edited Aug 19, 2015 at 12:05 Amareesh 3682 gold badges5 silver badges19 bronze badges asked Aug 19, 2015 at 11:40 user1587520user1587520 4,5832 gold badges22 silver badges21 bronze badges 7
  • Added a bounty to this, been a pain for me as well. – James Commented Feb 16, 2016 at 20:03
  • I was gonna propose to use angular to form the request xD – RaidenF Commented Feb 22, 2016 at 11:53
  • 1 Could you explain why you need this? Normally, the server-side code works out the size of each "part" in the multipart data by looking for the boundary delimiter, parsing the headers, etc - whatever is left is the data. Do you need to know the size of each part before you parse the body of each "part" for some reason? – sheltond Commented Feb 22, 2016 at 13:33
  • I don't this is possible. Angular uses native browser's functionality to serialize and send HTTP request. Content-Type and Content-Disposition are set by browser, not by Angular. – Volodymyr Usarskyy Commented Feb 23, 2016 at 14:49
  • 1 Well, tools.ietf/html/rfc2046 says "The only header fields that have defined meaning for body parts are those the names of which begin with 'Content-'". This implies that it's a valid thing to add a content-length header, but it doesn't seem like the HTML5 FormData class allows you to do it. That class is only really doing the multipart encoding, so you could use an alternative, but I haven't been able to find one with a brief search that does what you want. – sheltond Commented Feb 23, 2016 at 17:20
 |  Show 2 more ments

1 Answer 1

Reset to default 5 +100

I don't believe there is a way to actually add a custom header for each form data element. However why don't you add it to the content disposition header, as part of the file name:

data = new FormData();
data.append('additional-field-1', new Blob(['some plain text'], {type : 'text/plain'}));

for (var i = 0; i< $( '#file' )[0].files.length; i++) {
   var fileObj = $( '#file' )[0].files[i];
   data.append( '{ size : ' + fileObj.size + ' }' , $( '#file' [0].files[i], $( '#file' )[0].files[i].name );
}

I'm not sure how you are handling this on the server, but the request would look like this:

------WebKitFormBoundarysZxMHYOzMkqDmOvR
Content-Disposition: form-data; name="additional-field-1"; filename="blob"
Content-Type: text/plain


------WebKitFormBoundarysZxMHYOzMkqDmOvR
Content-Disposition: form-data; name="{ size : 22984 }"; filename="MatrixArithmetic.vshost.exe"
Content-Type: application/x-msdownload


------WebKitFormBoundarysZxMHYOzMkqDmOvR
Content-Disposition: form-data; name="{ size : 187 }"; filename="MatrixArithmetic.vshost.exe.config"
Content-Type: application/xml


------WebKitFormBoundarysZxMHYOzMkqDmOvR--

本文标签: javascriptSet contentlength header on individual parts of a multipartformdata uploadStack Overflow