Javascript fetch - 多部分/表单数据 POST 中缺少边界

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39280438/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 22:24:52  来源:igfitidea点击:

fetch - Missing boundary in multipart/form-data POST

javascriptxmlhttprequestfetchform-datafetch-api

提问by James

thanks for stopping by.

感谢您的光临。

I want to send a new FormData()as the bodyof a POSTrequest using the fetch api

我想送new FormData()body一个的POST使用请求提取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

boundary=----WebKitFormBoundaryyEmKNDsBKjB7QEqu

never makes it into the Content-Type:header

永远不会进入Content-Type:标题

it should look like this

它应该是这样的

Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryyEmKNDsBKjB7QEqu

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

Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryyEmKNDsBKjB7QEqu

so my question is,

所以我的问题是

  1. how do I make fetchbehave exactly like XMLHttpRequestin this situation?

  2. if this is not possible, why?

  1. 在这种情况下,我如何使fetch行为完全一样XMLHttpRequest

  2. 如果这是不可能的,为什么?

Thanks everybody! This community is more or less the reason I have professional success.

谢谢大家!这个社区或多或少是我取得职业成功的原因。

回答by James

The solution to the problem is to explicitly set Content-Typeto undefinedso that your browser or whatever client you're using can set it and add that boundary value in there for you. Disappointing but true.

问题的解决方案是显式设置Content-Type为,undefined以便您的浏览器或您使用的任何客户端可以设置它并为您添加该边界值。令人失望但真实。

回答by moonreader

fetch(url,options)
  1. If you set a string as options.body, you have to set the Content-Typein request header ,or it will be text/plainby default.
  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-Typeby 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 is application/x-www-form-urlencoded;
  1. 如果将字符串设置为options.body,则必须设置Content-Typein 请求标头,否则将text/plain默认设置。
  2. 如果 options.body 是特定对象,例如let a = new FormData()let b = new URLSearchParams(),则不必Content-Type手动设置。它将自动添加。

    • 因为a,它会像

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

    如您所见,边界是自动添加的。

    • 对于b,它是application/x-www-form-urlencoded;

回答by ravichandra vydhya

I removed "Content-Type" and added 'Accept' to http headers and it worked for me. Here are the headers I used,

我删除了“内容类型”并将“接受”添加到 http 标头中,它对我有用。这是我使用的标题,

'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' 

      })

回答by Andrew Faulkner

I had the same issue, and was able to fix it by excluding the Content-Typeproperty, 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
  }
)

回答by Diego Troiti?o

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 undefinedand it worked like a charm.

我正在使用aurelia-api(aurelia-fetch-client 的包装器)。在这种情况下,Content-Type 默认为“application/json”。所以我将 Content-Type 设置为 undefined,它就像一个魅力。

回答by Nver Abgaryan

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}浏览器将为您生成一个边界,用于上传带有流媒体的文件部分和部分,如果您添加“多个/表单数据”,这意味着您应该创建流媒体并上传您的文件部分和部分

So it is okay to add request.headers = {content-type: undefined}

所以添加 request.headers = {content-type: undefined} 就可以了