Composing multipart/form-data with a different Content-Type on each parts with Javascript (or Angular) Composing multipart/form-data with a different Content-Type on each parts with Javascript (or Angular) angularjs angularjs

Composing multipart/form-data with a different Content-Type on each parts with Javascript (or Angular)


According to the documentation of FormData, you can append a field with a specific content type by using the Blob constructor:

var formData = new FormData();formData.append('items', new Blob([JSON.stringify({    name: "Book",    quantity: "12"})], {    type: "application/json"}));

After careful observation, it turns out that it will send the part as follows:

Content-Disposition: form-data; name="items"; filename="blob"Content-Type: text/json

The only alternative, safe from building the whole request yourself is to pass a string value:

formData.append('items', '{"name": "Book", "quantity": "12"}');

This, unfortunately, doesn't set the Content-Type header.


Mistake #1: I mistakenly assume that the items has to be a json, so that we can call its attribute.

Solution: To submit a multipart request that contain a file and an object like format is very simple.

form = new FormData();form.append('items[name]', 'Book');form.append('items[quantity]', 12);form.append('image', imageFile);form.append('owner', 'John Doe');

So thus the request header and body will looks something like this

POST /api/v1/inventoryHost: localhost:8000Origin: http://localhost:9000Content-Type: multipart/form-data; boundary=------border------borderContent-Disposition: form-data; name="owner"john doe------borderContent-Disposition: form-data; name="image"; filename="mybook.png"Content-Type: image/png------borderContent-Disposition: form-data; name="items[name]"Book------borderContent-Disposition: form-data; name="items[quantity]"12------border--


Nothing would get this to work, until I set the Content-Type header to undefined. In my case I am posting a file and some json.

public uploadFile(code: string, file):angular.IHttpPromise<any>{    var data = `{"query":"mutation FIRMSCORECARD_CALCULATE($code:String!){ FirmScorecardMutation{ BatchCalculate(Code:$code) }}","variables":{"code":"${code}"},"operationName":"FIRMSCORECARD_CALCULATE"}`;    var formData = new FormData();    formData.append('operations', data);    formData.append('file', file, file.name);    let config = {        headers: {            'Accept': 'application/json',            'Content-Type': undefined        }    };    let response = this.$http.post(this.graphqlUrl, formData, config);    return response;}