You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nginx 1.19.0文件上传触发415错误,请求技术排查

解决Nginx上传模块+jQuery AJAX文件上传的415/400错误

问题分析

先理清楚为什么不同请求方式结果不一样:

  • curl上传正常:因为curl会自动生成完整且正确的multipart/form-data请求头(包含动态生成的boundary参数),Nginx上传模块能正确解析请求体。
  • jQuery设置contentType: false返回415:大概率是请求头或FormData构造有问题,导致Nginx无法识别请求的媒体类型。
  • 强制设置contentType: 'multipart/form-data'返回400:这个操作本身就有问题——multipart/form-data必须搭配boundary参数才能正确分割请求体中的字段,手动设置时没有这个动态生成的边界值,Nginx无法解析请求体,直接返回400。

解决方案

1. 修正FormData的构造(最常见原因)

确保你正确构造了FormData对象,没有遗漏文件字段或格式错误:

// 正确的FormData构造示例
var formData = new FormData();
// 绑定文件输入框的文件(假设输入框id为fileInput)
formData.append('file', $('#fileInput')[0].files[0]);
// 如果有其他表单字段(比如描述),也需要添加进去
formData.append('description', $('#description').val());

2. 调整jQuery AJAX配置并检查版本

  • 去掉async: false:同步请求会阻塞浏览器,且现代浏览器会发出警告,改为异步请求更合理。
  • 确保使用较新版本的jQuery:旧版本(比如1.9以下)在处理contentType: false和processData: false时可能存在bug,建议升级到3.x稳定版。
  • 保持contentType: false和processData: false不变,这两个选项是让浏览器自动处理请求头和表单数据的关键。

修正后的AJAX代码:

$.ajax({
    url: '/upload',
    type: 'POST',
    data: formData,
    async: true, // 改为异步
    cache: false,
    contentType: false,
    processData: false,
    success: function (response) {
        alert(response);
    },
    error: function(xhr) {
        console.log('请求错误:', xhr.status, xhr.responseText);
    }
});

3. 检查Nginx配置与日志

  • 确认Nginx已正确加载上传模块:执行nginx -V,查看输出中是否包含--with-http_upload_module(编译安装场景)或确认模块已通过动态加载方式启用。
  • 查看Nginx错误日志(通常在/var/log/nginx/error.log):415错误的详细原因会记录在这里,比如是否是Nginx拒绝了该文件的MIME类型。如果是,在location /upload块中添加upload_accept all;来允许所有类型的文件上传:
    location /upload {
        upload_pass @test;
        upload_store /tmp 1;
        upload_store_access user:r;
        upload_accept all; # 添加这一行允许所有文件类型
        # 其他配置...
    }
    
  • 确保/tmp目录及其子目录(0-9)的权限正确:Nginx进程的用户(通常是nginx或www-data)需要有写入权限,可执行chown -R nginx:nginx /tmp并确认权限为700左右。

4. 尝试原生XMLHttpRequest替代jQuery

如果上述方法都无效,可能是jQuery的AJAX封装有问题,改用原生XHR试试:

var xhr = new XMLHttpRequest();
xhr.open('POST', '/upload', true);
xhr.onload = function() {
    if (xhr.status === 200) {
        alert(xhr.responseText);
    } else {
        alert(`上传失败,状态码:${xhr.status}`);
    }
};
xhr.send(formData);

内容的提问来源于stack exchange,提问作者user12066

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 22:17:50