我正在 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 中使用带有
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
标头,包括必要的边界参数。希望这应该可以解决问题,并且您的服务器应该能够正确处理请求。