Why you should leave the UA to set the Multipart Content-Type header
While trying to create a simple node.js multipart request body parser, I noticed that by explicitly setting the Content-Type header to multipart/form-data when making an XMLHttpRequest to the server, actually overrides the important boundary token that should have followed the header as computed by the browser during the encoding process.
While researching on the format of Multipart content transmission, the spec actually mandates the UA to include the boundary token used in separating the body parts right in the Content-Type header. This boundary token must be unique and not appear within the body parts.
Below is a request I made to the server that explicitly sets the Content-Type header on the XMLHttpRequest to multipart/form-data
.
let xhr = new XMLHttpRequest(),
formData = new FormData();formData.append('userName', 'harrison');
formData.append('email', 'someone@example.com');
formData.append('password', 'random22');xhr.open('POST', 'user/create', true);
xhr.setRequestHeader('Content-Type', 'multipart/form-data');xhr.send(formData);
Request snapshot
Here is a request that leaves the implementation up to the User Agent. I did not explicitly set the Content-Type header. The UA sets the appropriate header.
let xhr = new XMLHttpRequest(),
formData = new FormData();formData.append('userName', 'harrison');
formData.append('email', 'someone@example.com');
formData.append('password', 'random22');xhr.open('POST', 'user/create', true);xhr.send(formData);
I strongly believe that almost all JavaScript Ajax library would not fall for this. If not, it would be an extra task for parsers as they would have to rightly guess the boundary token… in order to make any meaningful parse.