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。
大文件的正确姿势
超过几百 MB 的上传,不建议硬穿应用服务器:用对象存储预签名 URL 让浏览器直传 OSS/S3,Nginx 和应用只处理小请求。既绕开所有 body 限制,又省下大量带宽和内存。
观测云对照
413 在日志里是明明白白的信号。把 Nginx 访问日志接入观测云,按 URI 聚合 413——哪个上传接口在批量拒绝、拒绝的请求体多大,一查便知;对 413 数量设告警,限额配置被回滚或前置 CDN 变更导致的问题能立刻发现。
常见问题(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)——所以不至于撑爆内存,但临时目录所在分区要有足够磁盘。