使用“fetch”或“request”发送多部分/表单数据的正确方法

Dra*_*gar 4 javascript ajax fetch reactjs

这是我要发送到服务器的数据的结构:

{
   attachment: [File],
   foo: String,
   bar: String
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我正在尝试发送一组文件以及一些其他数据。为了存储所有这些数据,我使用了FormData()JavaScript 官方 API 中提供的构造函数。formData我正在这样填充:

for (let i = 0; i < this.state.files.length; i++) {
    let f = this.state.files[i];
    this.formData.append('attachment', f, f.name);
}
this.formData.append('foo', this.state.foo);
this.formData.append('bar', this.state.bar);
Run Code Online (Sandbox Code Playgroud)

旁注:使用 React,react-dropzone进行文件上传。我现在正在尝试将此数据提交到服务器。我首先尝试使用 Fetch API,如下所示:

fetch(url, {
    method: method,
    body: data,
    headers: {
      ...authHeader(authToken)
    }
}
Run Code Online (Sandbox Code Playgroud)

没有太多的成功。方法是POST. authHeader(authToken)只是生成Authorization: Bearer .... 问题是我认为指定的标头被我的身份验证标头覆盖。

所以我尝试使用request和request-promise-native。我做了类似的事情:

rp({
    url,
    method,
    headers: {
      ...authHeader(authToken)
    },
    formData: data
});
Run Code Online (Sandbox Code Playgroud)

具有类似的结果。使用授权标头和来自的文件数组发送此类数据的正确方法是什么FormData?

rev*_*btz 6

这是获取对象中可用的选项

fetch(url, {
            method: "POST", // *GET, POST, PUT, DELETE, etc.
            mode: "cors", // no-cors, cors, *same-origin
            cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
            credentials: "same-origin", // include, *same-origin, omit
            headers: {
                "Content-Type": "application/json",
                // "Content-Type": "application/x-www-form-urlencoded",
            },
            redirect: "follow", // manual, *follow, error
            referrer: "no-referrer", // no-referrer, *client
            body: JSON.stringify(data), // body data type must match "Content-Type" header
        })
Run Code Online (Sandbox Code Playgroud)

如果您需要向服务器发送一些自定义标头,只需这样编写:

headers: {
           "My-Custom-Header": "Custom-Header-Value",
         }
Run Code Online (Sandbox Code Playgroud)

因为您想发送多部分表单数据,所以您只需将数据添加到请求正文中,如下所示:

body: formData 
Run Code Online (Sandbox Code Playgroud)

如果您的字段位于表单标签内,您可以像这样设置表单数据:

var formData = new FormData(document.querySelector("form"));
Run Code Online (Sandbox Code Playgroud)

如果您使用 http 身份验证,则有不同的身份验证方案,请使用此链接作为参考 https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication

如果您使用基本授权,那么您应该使用如下内容:

headers: {
           'Authorization': 'Basic '+btoa('username:password')
         }
Run Code Online (Sandbox Code Playgroud)