简体   繁体   English

fetch - multipart/form-data POST 中缺少边界

[英]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,所以我的问题是

  1. how do I make fetch behave exactly like XMLHttpRequest in this situation?在这种情况下,如何使fetch的行为与XMLHttpRequest完全一样?

  2. 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)
  1. If you set a string as 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
  2. 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 。它将自动添加。

    • for a ,it will be something like对于a ,它会像

    multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

    as you see, the boundary is automaticlly added.如您所见,边界是自动添加的。

    • for 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 ,您有两种方法可以修复它:

  1. rewrote your code (or whatever you use) to don't set Content-Type by default重写您的代码(或您使用的任何代码)以默认不设置Content-Type
  2. set 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.

相关问题 php 消息警告:在第 0 行未知的多部分/表单数据 POST 数据中缺少边界 - php message Warning: Missing boundary in multipart/form-data POST data in Unknown on line 0 警告:在第0行的Unknown中,multipart / form-data POST数据中缺少边界 - Warning: Missing boundary in multipart/form-data POST data in Unknown on line 0 使用XMLHttprequest上传文件 - 在multipart / form-data中缺少边界 - Uploading a file with XMLHttprequest - Missing boundary in multipart/form-data XMLHttpRequest multipart / form-data:多部分中的边界无效 - XMLHttpRequest multipart/form-data: Invalid boundary in multipart FormData如何在多部分/表单数据中获取或设置边界 - Angular - FormData how to get or set boundary in multipart/form-data - Angular 如何将文件发布到多部分/表单数据? - How to post files to a multipart/form-data? XMLHttpRequest POST multipart / form-data - XMLHttpRequest POST multipart/form-data Javascript / AJAX POST多部分/表单数据 - Javascript/AJAX POST multipart/form-data 通过 Safari 中的 multipart/form-data 发布的文件上传服务工作人员未触发“获取”事件侦听器 - "fetch" event listener not triggering in service worker for file upload via multipart/form-data post in Safari 使用`fetch`或`request`发送多部分/表单数据的正确方法 - Proper way to send multipart/form-data using `fetch` or `request`
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM