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

fetch - Missing boundary in multipart/form-data POST

感谢您的光临。

我想发送 new FormData() 作为 POST 请求的 body 使用 fetch api

操作看起来像这样

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
  }
)

这里的问题是边界,像

boundary=----WebKitFormBoundaryyEmKNDsBKjB7QEqu

从未进入 Content-Type: header

它应该是这样的

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

当您使用 new XMLHttpRequest() 尝试 "same" 操作时,就像这样

var request = new XMLHttpRequest()
request.open("POST", "https://api.mything.com")
request.withCredentials = true
request.send(formData)

header设置正确

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

所以我的问题是,

  1. 如何让 fetch 在这种情况下表现得与 XMLHttpRequest 完全一样?

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

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

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

我正在使用 aurelia-api(aurelia-fetch-client 的包装器)。 在这种情况下,Content-Type 默认值为 'application/json'。所以我 将 Content-Type 设置为未定义 并且效果很好。

fetch(url,options)
  1. 如果设置字符串为options.body,则必须在请求头中设置Content-Type,否则默认为text/plain
  2. 如果 options.body 是特定对象,例如 let a = new FormData()let b = new URLSearchParams(),您不必通过 [=42= 设置 Content-Type ] 将自动添加。

    • 对于a,它会像

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

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

    • b来说是application/x-www-form-urlencoded;

添加headers:{content-type: undefined}浏览器会为你生成一个边界 这是用于通过流式传输部分上传文件 如果您要添加 'multiple/form-data' 这意味着您应该创建流媒体并上传您的文件部分和部分

所以加上request.headers = {content-type: undefined}

就可以了

我删除了 "Content-Type" 并将 'Accept' 添加到 http headers 并且对我有用。这是我用的headers,

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

      })

我有同样的问题,并且能够通过排除 Content-Type 属性 来解决它,允许浏览器自动检测和设置边界和内容类型。

您的代码变为:

var formData = new FormData()
formData.append('myfile', file, 'someFileName.csv')

fetch('https://api.myapp.com',
  {
    method: 'POST',
    body: formData
  }
)