文件上传接口 404 故障排查记录,接口能正常访问
·
文件上传接口 404 故障排查记录,接口能正常访问
问题现象
- 文件上传流程:压缩完成后,点击上传按钮,分片上传接口返回 404 Not Found
- 错误信息:
POST /prod-api/service/uploadRecord/chunk 404 (Not Found),响应体为 Nginx 默认 404 HTML 页面 - 异常点:其他业务接口(如查询、初始化)调用正常,唯独上传相关的 POST 请求返回 404
- 初步判断:接口路径本身存在(初始化、检查接口可正常调用),但带有文件数据的 multipart 请求被拦截
排查过程
第一阶段:前端代码加日志
1. request.js 全局拦截器加调试日志
在 src/utils/request.js 的请求拦截器中,针对包含 uploadRecord 的请求打印详细配置:
- 请求方法(method)
- baseURL 与最终拼接 URL
- 请求头(headers)
- data 类型(是否为 FormData)
- Content-Type 是否被正确设置
同时增加保护逻辑:若 data 为 FormData,显式删除 Content-Type header,强制让浏览器自动设置为 multipart/form-data,排除 axios 全局 application/json 默认值干扰。
2. cdList.js chunk 接口加日志
在 src/api/cdList.js 的 chunk() 函数中,调用前打印:
VITE_HOST_UPLOAD_URL环境变量值- 拼接后的完整请求地址
- 入参数据类型
3. FileUploader 组件加全流程日志
在 src/components/FileUploader/index.vue 的 handleUpload 中,对以下节点上报/打印日志:
- 开始上传流程
- 文件 MD5 检查
- 初始化上传
- 分片上传(每片开始/成功/失败)
- 合并分片
- 保存报告记录
- 整体成功/失败
并在分片上传失败时,自动触发 fetch 降级对比测试,同时用 fetch 发送完全相同的 FormData,对比 axios 与 fetch 的差异。
第二阶段:浏览器独立测试页面
编写独立的 HTML 测试页面(不依赖项目代码),在浏览器环境中直接对接口进行控制变量测试:
| 测试项 | 目的 |
|---|---|
| fetch 空 POST | 验证接口路径是否存在 |
| fetch FormData(假 Blob) | 验证不带文件名的表单提交 |
| axios FormData(假 Blob) | 验证 axios 库本身是否有特殊行为 |
| axios + 强制 json Content-Type | 验证 Content-Type 错误时的表现 |
| fetch 上传真实 ZIP 文件 | 模拟真实场景(带真实文件名、文件大小、二进制内容) |
| axios 上传真实 ZIP 文件 | 与 fetch 真实文件测试做对比 |
测试页面支持填入 Authorization Token,可对比带 Token 与不带 Token 时的服务器响应差异。
第三阶段:对比验证
关键发现 1:URL 与路径本身没有问题
- 空 POST 请求可正常到达服务器(返回 400 参数校验错误,而非 404)
/service/uploadRecord/check、/service/uploadRecord/init等接口调用正常- 说明接口路径在服务器上是存在的
关键发现 2:axios vs fetch 行为一致
- 在独立测试页面中,fetch 和 axios 只要携带真实文件,都会返回 404
- 排除 axios 库本身(如 Content-Type 污染、header 自动添加等)导致的问题
- 确认问题在服务器层,而非前端代码层
关键发现 3:带文件即 404,不带文件即正常
- 不携带
chunk文件字段的请求 → 正常返回(400 或 200) - 携带
chunk文件字段(无论 fetch 还是 axios)→ 返回 404 - 最终定位:Nginx 层面对 multipart/form-data 上传请求做了拦截或限制
根因结论
Nginx 服务器配置对文件上传请求做了限制,具体表现为:
- 普通 JSON 接口请求 → 正常转发到后端服务
multipart/form-data文件上传请求 → Nginx 直接返回 404,请求未到达后端应用服务
可能的具体原因(需运维/后端确认):
- Nginx
client_max_body_size配置为 0 或未开启,导致直接拒绝上传请求 - Nginx 配置了基于 Content-Type 或请求体的访问控制规则,拦截了 multipart 请求
- Nginx 缺少对应 location 的
proxy_pass配置,或上传流量被路由到了不存在该接口的 upstream - 安全模块(如 WAF、ModSecurity)规则拦截了文件上传
后续修复建议
- 运维侧:检查 Nginx 配置中
client_max_body_size是否设置为合理值(建议 >= 100M,与业务分片大小匹配) - 运维侧:确认上传接口的 location 块是否正确配置了
proxy_pass,且上传流量被转发到正确的后端服务 - 运维侧:检查 Nginx 访问日志(
access.log),确认 404 是由 Nginx 本身返回还是后端返回 - 后端侧:确认上传服务是否部署在正确的 upstream 节点上,与不带认证的公共服务节点区分开
经验总结
- 前端排查三板斧:加日志 → 独立测试页 → 控制变量对比
- 当 fetch 和 axios 表现一致时,问题基本可锁定在服务器/网络层,无需在前端代码上过度排查
- 404 不一定代表"路径不存在":Nginx 可能因请求特征(如 Content-Type、Body 大小)主动拒绝请求并返回 404
- 真实文件测试很关键:用假 Blob 测试可能无法触发服务器对文件上传的限制策略,必须使用真实文件对象
相关代码改动(排查期间)
以下文件在排查过程中被修改用于加日志或测试,修复完成后可根据需要保留或移除调试代码:
| 文件 | 改动说明 |
|---|---|
src/utils/request.js |
增加上传请求调试日志 + FormData Content-Type 保护 |
src/api/cdList.js |
chunk() 函数增加调用前日志 |
src/components/FileUploader/index.vue |
上传全流程日志 + fetch 降级对比测试 |
tests/test-upload-chunk.html |
浏览器独立测试页面(fetch/axios/真实文件上传对比) |
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)