Nginx 文件上传报 413 Request Entity Too Large 怎么办?
Nginx 413 上传失败:client_max_body_size 默认仅 1M,调大即可;http/server/location 三级作用域、应用层与 PHP 配套限制、CDN 前置限制与 FAQ。
413 表示请求体超过 Nginx 的 client_max_body_size 限制——默认值只有 1MB,现代应用稍大的图片/文件上传就会撞线。调大这个值即可:
http {
client_max_body_size 100M; # 全局:http 块
}
# 或只给上传接口放开
location /upload {
client_max_body_size 500M; # location 级,就近优先
}
改完 nginx -t && systemctl reload nginx。
三级作用域
client_max_body_size 可以出现在 http、server、location 任意层级,内层覆盖外层。排障时用 nginx -T 看最终生效值——常见翻车是全局调大了,某个 location 里却单独写了个小值。
别忘了整条链路上的其他限制
Nginx 放行了不代表后面接得住,逐层对齐:
- PHP:
php.ini的upload_max_filesize(单文件)和post_max_size(整个 POST 体)都要 ≥ Nginx 的值;改完重启 PHP-FPM。 - 应用框架:Express
express.json({limit})、Springspring.servlet.multipart.max-file-size、DjangoDATA_UPLOAD_MAX_MEMORY_SIZE等各有限制。 - 反向代理上游:上游若也是 Nginx 或别的网关,它还有一层限制。
- CDN/LB:CloudFront、Cloudflare(免费版 100MB)、部分 SLB 对请求体有硬性上限,超了只能走分片上传或直连。
- 超时联动:大文件上传慢,顺手检查
client_body_timeout与上游超时,别 413 修好了改 504。
验证限额时,分别发送略低于和略高于阈值的请求,并检查每层入口的记录。把 Nginx 日志通过 DataKit接入观测云后,可按 URI 与 413 状态筛选受影响接口;请求体大小只有在日志中记录并解析了对应字段时才能查询,不能从 413 本身推算。
大文件的正确姿势
超过几百 MB 的上传,不建议硬穿应用服务器:用对象存储预签名 URL 让浏览器直传 OSS/S3,Nginx 和应用只处理小请求。既绕开所有 body 限制,又省下大量带宽和内存。
常见问题(FAQ)
Q:client_max_body_size 设为 0 是无限制吗?
A:是——0 表示不检查。但等于敞开大门接受任意大小的请求体,内存/磁盘压力大增,生产环境不建议。
Q:改了还是 413,nginx -T 里值也对?
A:请求可能根本没到这台 Nginx——前面还有 CDN/SLB/另一层反代,413 是它们返回的。看响应头里的 Server 字段,或在 Nginx 访问日志里确认请求是否到达。
Q:大 body 会占多少内存?
A:Nginx 默认把 body 缓冲到 client_body_buffer_size,超出写临时文件(client_body_temp_path)——所以不至于撑爆内存,但临时目录所在分区要有足够磁盘。