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

时间:2016-09-01 20:34:00

标签: javascript xmlhttprequest fetch form-data fetch-api

感谢您的光临。

我想使用fetch api

发送new FormData() body作为POST请求的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:

永远不会进入Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryyEmKNDsBKjB7QEqu标题

它看起来应该是这样的

new XMLHttpRequest()

当你尝试"相同"使用var request = new XMLHttpRequest() request.open("POST", "https://api.mything.com") request.withCredentials = true request.send(formData)进行操作,如此



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




标题已正确设置

fetch

所以我的问题是,

  1. 在这种情况下,如何使XMLHttpRequest的行为与class Author{ public int Id{get;set;} public string Name{get;set;} //..... } class Article{ public int Id{get;set;} public int AuthorId{get;set;} public string Text{get;set;} } 完全相同?

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

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

6 个答案:

答案 0 :(得分:68)

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

答案 1 :(得分:6)

fetch(url,options)
  1. 如果您将字符串设置为options.body,则必须在请求标头中设置Content-Type,否则默认为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;

答案 2 :(得分:3)

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

答案 3 :(得分:3)

我删除了“ Content-Type”,并在HTTP标头中添加了“ Accept”,它对我有用。这是我使用的标题,

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

      })

答案 4 :(得分:1)

添加headers:{content-type: undefined}浏览器将为您生成一个边界 用于通过流媒体部分上传文件 如果您要添加“多个/表单数据”,则意味着您应该创建流媒体并分批上传文件

因此可以添加request.headers = {content-type:undefined}

答案 5 :(得分:0)

我遇到了同样的问题,并且能够通过排除Content-Type属性来解决此问题,从而使浏览器能够自动检测并设置边界和内容类型。

您的代码变为:

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

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