javascript - nginx 1.19.0:上传文件时出现 415 错误
问题描述
我正在使用 nginx 提供一个页面,该页面包含一个用于将文件上传到服务器的表单。我在 POST 请求中使用 FormData() 类作为我的数据:
js:
$.ajax({
url: /upload,
type: 'POST',
data: formData,
async: false,
cache: false,
contentType: false,
enctype: 'multipart/form-data',
processData: false,
success: function (response) {
alert(response);
}
});
我正在使用示例 nginx 上传模块,使用此页面底部的默认配置:https ://www.nginx.com/resources/wiki/modules/upload/ :
location /upload {
# Pass altered request body to this location
upload_pass @test;
# Store files to this directory
# The directory is hashed, subdirectories 0 1 2 3 4 5 6 7 8 9 should exist
upload_store /tmp 1;
# Allow uploaded files to be read only by user
upload_store_access user:r;
# Set specified fields in request body
upload_set_form_field $upload_field_name.name "$upload_file_name";
upload_set_form_field $upload_field_name.content_type "$upload_content_type";
upload_set_form_field $upload_field_name.path "$upload_tmp_path";
# Inform backend about hash and size of a file
upload_aggregate_form_field "$upload_field_name.md5" "$upload_file_md5";
upload_aggregate_form_field "$upload_field_name.size" "$upload_file_size";
upload_pass_form_field "^submit$|^description$";
upload_cleanup 400 404 499 500-505;
}
# Pass altered request body to a backend
location @test {
proxy_pass http://localhost:8080;
}
我没有使用任何 PHP 脚本或其他任何东西;我的印象是默认的上传模块配置只会将上传的文件转储到 /tmp/1(我已经创建了这个目录并授予了 nginx 的写权限)。该文件只有几 kb,因此文件大小应该没有问题。
当我尝试上传文件时,我收到 HTTP 415 错误,即不支持的媒体类型。我上传的文件有一个扩展名 .bin,这是 /etc/nginx/mime.types 文件中支持的 MIME 类型。
我可以使用 cURL 在命令行上发出类似的请求:
curl -F 'file@=myfile.bin' http://<URL>/upload
这很好用。检查 curl 的输出,我在 POST 标头中看到了
Content-Type: multipart/form-data; boundary=-------etc
但这在上面的 jQuery ajax 调用中被禁用为
Content-Type: false;
正如 SO 帖子中所建议的那样,我如何异步上传文件?. 如果我在对 multipart/form-data 的 ajax 调用中强制使用 Content-Type,则会收到 400 Bad Request 错误。有人可以解释我要去哪里错了吗?
解决方案
所以似乎当使用 FormData 类发布表单数据时,jquery ajax POST 方法将通过
Content-Type: false
对后端服务器的权限,在本例中为 nginx。nginx 无法识别此内容类型,因此出现 415 错误。我找不到解决这个问题的直接答案,所以我不得不求助于一个简单的 XMLHTTPRequest:
var form = document.getElementById("MyFormId");
var req = new XMLHTTPRequest();
req.open('POST', url, true);
req.onprogress = function () {
// handle progress
}
req.onload = function () {
// successful request
}
req.onerror= function () {
// request in error
}
req.send(new FormData(form));
event.preventDefault();
当我发送这个时,表单数据会原封不动地进入 nginx 并在 HTTP 请求中
Content-Type: 'multipart/form-data'
就像我看到的使用 cURL 一样。
我希望这对某人有用。
推荐阅读
- python - 在 Flask 中为 Preflight 请求配置特定标头
- java - 使用java分区负正不与0比较
- redux - Redux Toolkit - 重置状态
- python - 想知道为什么 scipy.spatial.distance.sqeuclidean 比 numpy.sum((y1-y2)**2) 慢两倍
- python - 如何在python中并行集成for循环以在CLUSTER中运行
- javascript - MathUtils.euclideanModulo 的用途是什么,它与常规模数有何不同?
- python - 仅从浏览器中打开的页面获取数据
- xamarin - 如何在 Xamarin.UITest 项目中使用 WireMock.Net?
- android - 如何在android studio中指定另一个api级别的SDK源代码
- babeljs - core-js 无法解析 core-js/modules/es6.typed.uint32-array