必须在匹配上传路径的location块中显式配置client_max_body_size,因Nginx优先级为location>server>http;还需同步调大client_body_buffer_size、client_body_temp_path权限、proxy_read_timeout等配套参数,否则仍会因缓冲、超时或权限问题导致上传失败。

只改 client_max_body_size 不能解决上传失败问题,413 错误只是表象,背后常是缓冲、权限或超时连环失效。
为什么改了 client_max_body_size 还报 413?
因为 Nginx 的匹配优先级是 location > server > http。如果你在 http 块里设了 client_max_body_size 500m,但上传请求走的是 location /api/upload,而该 location 块里没重写这个值,它就会继承更上层的默认值(通常是 1m),而不是你期望的 500m。
- 浏览器上传接口路径是
/upload,就必须在对应location /upload { ... }里显式写client_max_body_size - 在
server块设虽能覆盖多数路径,但会把登录、表单等非上传接口也放宽,增加攻击面 - 单位拼写敏感:
500mb合法,500MB或500Mb可能因大小写不一致被忽略
client_max_body_size 必须和哪些参数一起调?
它只管“让不让进”,不管“稳不稳传”。大文件上传要跑通,以下三项必须同步检查:
-
client_body_buffer_size:建议设为512k~1m。太小(如默认8k)导致频繁刷盘到磁盘;太大(比如设成和client_max_body_size一样)会吃光内存,仅适合极低流量场景 -
client_body_temp_path:确认路径(默认/tmp)磁盘空间充足,且 Nginx 运行用户(如www-data或nginx)对该路径有读写权限,否则日志里会出现open() failed (13: Permission denied) -
proxy_read_timeout和proxy_send_timeout:建议都设为3600(1 小时)。Nginx 在转发给后端前需完整收完请求体,超时就直接断连,前端看到的是网络错误,不是 413
怎么验证配置真生效了?别只信浏览器
浏览器点选上传容易受前端 JS 校验、缓存或网络抖动干扰,真实验证得用命令行发原始 multipart 请求:
- 用
curl -F "file=@test.zip" http://your-domain.com/api/upload测试,观察返回码是 200 还是 413 - 实时盯
tail -f /var/log/nginx/error.log,出现client intended to send too large body表示限制已起效;出现Permission denied或upstream timed out则说明是权限或超时问题 - 如果后端是 PHP,还要同步检查
upload_max_filesize、post_max_size、max_execution_time等,否则请求会在 Nginx 之后卡死
最容易被忽略的是 client_body_temp_path 权限和 proxy_read_timeout——它们不出现在任何错误页里,却能让上传在无声中失败。上线前务必用真实大文件 + curl + error.log 三者交叉验证。


















