This is the structure of the data I want to send to the server:
{
   attachment: [File],
   foo: String,
   bar: String
}
As you can see, I am trying to send an array of files along with some other data. For storing all this data, I used FormData() constructor provided in the JavaScript official API. I am populating the formData like this:
for (let i = 0; i < this.state.files.length; i++) {
    let f = this.state.files[i];
    this.formData.append('attachment', f, f.name);
}
this.formData.append('foo', this.state.foo);
this.formData.append('bar', this.state.bar);
Sidenote: using React, react-dropzone for file upload.
I am now trying to submit this data to the server. I first tried using the Fetch API like so:
fetch(url, {
    method: method,
    body: data,
    headers: {
      ...authHeader(authToken)
    }
}
Without too much success. Method is POST. authHeader(authToken) just generates Authorization: Bearer .... Problem was I think that the headers that get specified get overridden by my authentication header.
So I tried using request and request-promise-native. I did something like:
rp({
    url,
    method,
    headers: {
      ...authHeader(authToken)
    },
    formData: data
});
With similar results. What is the proper way to send this kind of data with Authorization Header and an array of Files from FormData?
This are the options available in the fetch object
fetch(url, {
            method: "POST", // *GET, POST, PUT, DELETE, etc.
            mode: "cors", // no-cors, cors, *same-origin
            cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
            credentials: "same-origin", // include, *same-origin, omit
            headers: {
                "Content-Type": "application/json",
                // "Content-Type": "application/x-www-form-urlencoded",
            },
            redirect: "follow", // manual, *follow, error
            referrer: "no-referrer", // no-referrer, *client
            body: JSON.stringify(data), // body data type must match "Content-Type" header
        })
If you need to send some custom header to the server just write it like this:
headers: {
           "My-Custom-Header": "Custom-Header-Value",
         }
And because you want to send a multipart-form data you need to just add the data to the body of the request like this:
body: formData 
If you have your fields inside a form tag you could set your form data like this:
var formData = new FormData(document.querySelector("form"));
If you are using http authentication there are different authentication schemes, for reference use this link https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication
If your are using basic authorization then you should use something like this:
headers: {
           'Authorization': 'Basic '+btoa('username:password')
         }
For future reference, I managed to send the data with the following configuration:
fetch(url, {
    method: method,
    body: data,
    headers: {
        'Accept': 'application/json',
        ...authHeader(authToken)
    }
})
That is, passing through the Accept header seems to have fixed the issue. Please also note that the Content-Type header is not set, allowing browser to set it by itself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With