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
fetch
behave exactly likeXMLHttpRequest
in 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-Type
in request header ,or it will betext/plain
by default. If options.body is specific object like
let a = new FormData()
orlet b = new URLSearchParams()
, you don't have to set theContent-Type
by hand.It will be added automaticlly.- for
a
,it will be something like
multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
as 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