thanks for stopping by.
I want to send a new FormData() as the body of a POST request using the fetch api
the operation looks something like this
var formData = new FormData()
formData.append('myfile', file, 'someFileName.csv')
fetch('https://api.myapp.com',
{
method: 'POST',
headers: {
"Content-Type": "multipart/form-data"
},
body: formData
}
)
the problem here is that the boundary, something like
boundary=----WebKitFormBoundaryyEmKNDsBKjB7QEqu
never makes it into the Content-Type: header
it should look like this
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryyEmKNDsBKjB7QEqu
when you try the "same" operation with a new XMLHttpRequest(), like so
var request = new XMLHttpRequest()
request.open("POST", "https://api.mything.com")
request.withCredentials = true
request.send(formData)
the headers are correctly set
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryyEmKNDsBKjB7QEqu
so my question is,
how do I make
fetchbehave exactly likeXMLHttpRequestin this situation?if this is not possible, why?
Thanks everybody! This community is more or less the reason I have professional success.
The solution to the problem is to explicitly set Content-Type to undefined so that your browser or whatever client you're using can set it and add that boundary value in there for you. Disappointing but true.
fetch(url,options)
- If you set a string as
options.body, you have to set theContent-Typein request header ,or it will betext/plainby default. If options.body is specific object like
let a = new FormData()orlet b = new URLSearchParams(), you don't have to set theContent-Typeby hand.It will be added automaticlly.- for
a,it will be something like
multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gWas you see, the boundary is automaticlly added.
- for
b, it isapplication/x-www-form-urlencoded;
- for
I removed "Content-Type" and added 'Accept' to http headers and it worked for me. Here are the headers I used,
'headers': new HttpHeaders({
// 'Content-Type': undefined,
'Accept': '*/*',
'Authorization':
"Bearer "+(JSON.parse(sessionStorage.getItem('token')).token),
'Access-Control-Allow-Origin': this.apiURL,
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, PUT, PATCH, DELETE',
'Access-Control-Allow-Headers': 'origin,X-Requested-With,content-type,accept',
'Access-Control-Allow-Credentials': 'true'
})
I'm using the aurelia-api (an wrapper to aurelia-fetch-client). In this case the Content-Type default is 'application/json'. So I set the Content-Type to undefined and it worked like a charm.
I had the same issue, and was able to fix it by excluding the Content-Type property, allowing the browser to detect and set the boundary and content type automatically.
Your code becomes:
var formData = new FormData()
formData.append('myfile', file, 'someFileName.csv')
fetch('https://api.myapp.com',
{
method: 'POST',
body: formData
}
)
Add headers:{content-type: undefined} browser will generate a boundary for you
that is for uploading a file part-and-part with streaming
if you are adding 'multiple/form-data' it means you should create streaming and upload your file part-and-part
So it is okay to add request.headers = {content-type: undefined}
来源:https://stackoverflow.com/questions/39280438/fetch-missing-boundary-in-multipart-form-data-post