在 Fetch 中使用 multipart/form-data 时无法访问请求中的数据

问题描述 投票:0回答:1

我正在 JavaScript 中使用 Fetch API。到目前为止,我在浏览器中内置的 Content-Type 标头上使用隐式设置。即:如果用户发送 JSON,浏览器会将 Content-Type 设置为

application/json
。如果我发送 FormData,浏览器会将 Content-Type 设置为
multipart/form-data

这效果很好,但我使用的是旧版本的捆绑器,它将我的网络应用程序构建为 Android 应用程序,该应用程序不会自动设置

content-type
标头。

为此,我需要明确定义我正在使用的内容类型。但是,当我明确指定内容类型时,服务器无法正确处理我的请求 - 服务器无法将提供的字段发送到 FormData 对象中。

这是我发送请求的方式:

var myHeaders = new Headers()
myHeaders.append("content-type", "multipart/form-data")

var formdata = new FormData();
formdata.append("email", "[email protected]");
formdata.append("password", "MySuperSecretPasswordOMG!");

var requestOptions = {
  method: 'POST',
  body: formdata,
  headers: myHeaders,
  redirect: 'follow'
};

console.log(formData) // Here I see FormData {email: "[email protected]", password: "MySuperSecretPasswordOMG!" }

fetch("http://192.168.1.123:5000/users/auth/login", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));

我的服务器响应错误代码 400,我编码为当请求中缺少任何必填字段时返回:

# Login validator created in Flask
data = request.form # email and password are NOT present in request.
required_keys = ["email", "password"]

if not self.validate(required_keys, data):
    return self._abort(400, "Incorrectly formatted request. Please make sure that all the required fields are entered.")

# Additional functions which are used above.
@staticmethod
def _abort(code, message):
    return jsonify({"msg": message, "code": code}), code

def validate(self, keys, data):
    for key in keys:
        if key not in data:
            return False
    return True

我做错了什么吗?这是与浏览器相关的问题吗?这是后端/前端相关的功能吗?

javascript fetch
1个回答
0
投票

在 JavaScript 中使用带有

multipart/form-data
的 Fetch API 时,请务必记住,在发送
Content-Type
时不应手动设置
FormData
标头。浏览器会自动设置正确的
Content-Type
标头,包括
multipart/form-data
所需的边界参数。

在您的情况下,将

Content-Type
显式设置为
"multipart/form-data"
可能会导致服务器无法正确处理请求的问题。缺少边界参数,这是服务器端解析
FormData
所必需的。

以下是修改提取请求的方法:

var formdata = new FormData();
formdata.append("email", "[email protected]");
formdata.append("password", "MySuperSecretPasswordOMG!");

var requestOptions = {
  method: 'POST',
  body: formdata,
  redirect: 'follow'
};

fetch("http://192.168.1.123:5000/users/auth/login", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));

在此修订后的代码中:

  • Content-Type
    标题未在
    myHeaders
    中手动设置。
  • 浏览器将自动为
    Content-Type
    设置正确的
    FormData
    标头,包括必要的边界参数。

希望这应该可以解决问题,并且您的服务器应该能够正确处理请求。

© www.soinside.com 2019 - 2024. All rights reserved.