[英]fetch - Missing boundary in multipart/form-data POST
thanks for stopping by.感谢您的光临。
I want to send a new FormData()
as the body
of a POST
request using the fetch api我想使用fetch api发送一个
new FormData()
作为POST
请求的body
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永远不会进入
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当您使用
new XMLHttpRequest()
尝试“相同”操作时,就像这样
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 like XMLHttpRequest
in this situation?在这种情况下,如何使
fetch
的行为与XMLHttpRequest
完全一样?
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.该问题的解决方案是将
Content-Type
显式设置为undefined
,以便您的浏览器或您使用的任何客户端都可以设置它并在其中为您添加该边界值。 Disappointing but true.令人失望但真实。
I removed "Content-Type" and added 'Accept' to http headers and it worked for me.我删除了“Content-Type”并将“Accept”添加到 http 标头,它对我有用。 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'
})
fetch(url,options)
options.body
, you have to set the Content-Type
in request header ,or it will be text/plain
by default.options.body
,则必须在请求标头中设置Content-Type
,否则默认为text/plain
。 If options.body is specific object like let a = new FormData()
or let b = new URLSearchParams()
, you don't have to set the Content-Type
by hand.It will be added automaticlly.如果 options.body 是特定对象,例如
let a = new FormData()
或let b = new URLSearchParams()
,则不必手动设置Content-Type
。它将自动添加。
a
,it will be something likea
,它会像multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
as you see, the boundary is automaticlly added.如您所见,边界是自动添加的。
b
, it is application/x-www-form-urlencoded;
b
,它是application/x-www-form-urlencoded;
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.我有同样的问题,并且能够通过排除
Content-Type
属性来解决它,允许浏览器自动检测和设置边界和内容类型。
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添加
headers:{content-type: undefined}
浏览器将为您生成一个边界,如果您要添加“multiple/form-data”,则该边界用于上传文件部分和部分流,这意味着您应该创建流并上传您的文件部分和部分
So it is okay to add request.headers = {content-type: undefined}所以添加 request.headers = {content-type: undefined} 就可以了
I'm using the aurelia-api (an wrapper to aurelia-fetch-client).我正在使用aurelia-api (aurelia-fetch-client 的包装器)。 In this case the Content-Type default is 'application/json'.
在这种情况下,Content-Type 默认为“application/json”。 So I set the Content-Type to undefined and it worked like a charm.
所以我将 Content-Type 设置为 undefined ,它就像一个魅力。
According to FormData documentation , you shoudn't manually set the Content-Type
header so browser itself will set it correctly:根据FormData 文档,您不应该手动设置
Content-Type
标头,因此浏览器本身会正确设置它:
Warning: When using FormData to submit POST requests using XMLHttpRequest or the Fetch_API with the multipart/form-data Content-Type (eg when uploading Files and Blobs to the server), do not explicitly set the Content-Type header on the request.
警告:当使用 FormData 提交使用 XMLHttpRequest 或 Fetch_API 与 multipart/form-data Content-Type 的 POST 请求时(例如,将文件和 Blob 上传到服务器时),不要在请求上显式设置 Content-Type 标头。 Doing so will prevent the browser from being able to set the Content-Type header with the boundary expression it will use to delimit form fields in the request body.
这样做会阻止浏览器使用边界表达式设置 Content-Type 标头,它将用于分隔请求正文中的表单字段。
So if your code (or library/middleware/etc) manually set the Content-Type
, you have two ways to fix it:因此,如果您的代码(或库/中间件/等)手动设置
Content-Type
,您有两种方法可以修复它:
Content-Type
by defaultContent-Type
Content-Type
to undefined
or remove it from headers
to let your browser do it's workContent-Type
设置为undefined
或将其从headers
中删除以让您的浏览器完成它的工作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.