当前位置:首页 >  IDC >  服务器 >  正文

Nginx 413 Request Entity Too Large:三处上传限制一起改才算改完

 2026-09-06 10:56  来源: 互联网   我来投稿 撤稿纠错

  一键部署OpenClaw

用户后台传一张 3MB 的图,页面转半天最后白屏,什么提示都没有。你去看浏览器请求,状态码 413 Request Entity Too Large。这个错误有个讨厌的特性:官方文档里明确写了浏览器没法正确渲染它,所以用户端看到往往不是 413 页面,而是一片白或者连接被重置,报障的时候只会说“传不上去”。

根因就一句话:Nginx 的 client_max_body_size 默认 1MB,请求体超过就直接拒,连后端的面都见不到。但很多人改完 Nginx 还是传不上去,是因为上传链路上一共卡着三道限制,只改一道等于没改。

# 第一道:Nginx(http/server/location 都可以设,location 优先级最高)
http {
client_max_body_size 100m;
client_body_buffer_size 128k; # 超过缓冲区的请求体会落盘临时文件
client_body_timeout 300s; # 大文件上传时默认 60s 可能不够
}

# 第二道:PHP 自身的上传限制(php.ini 或 FPM 的 conf.d 片段)
upload_max_filesize = 100M
post_max_size = 100M # 必须大于等于 upload_max_filesize
memory_limit = 256M # 官方建议 memory_limit 要比 post_max_size 大

# 第三道:FPM/Nginx 的超时,大文件传一半被掐断报的又是另一个错
# nginx: fastcgi_read_timeout 300; fastcgi: request_terminate_timeout = 300s

改完先做配置检查再重载,然后验证实际生效的值——用 nginx -T 把全量配置导出来 grep,比逐个文件翻靠谱,因为 client_max_body_size 可能同时写在 http 块、站点配置和某个 include 里,冲突时取的是最内层作用域的值。

nginx -t && systemctl reload nginx

# 确认当前生效的所有限制值
nginx -T 2>/dev/null | grep -n client_max_body_size

# PHP 侧确认(注意 FPM 和 CLI 是两套 php.ini,别改错对象)
php -i | grep -E "upload_max_filesize|post_max_size" # CLI
# FPM 侧建一个含 <?php phpinfo(); 的临时文件用浏览器看最准

# 用 curl 直接验证 413 是否消失:造一个 5MB 的测试文件上传
dd if=/dev/zero of=/tmp/test5m.bin bs=1M count=5
curl -sS -o /dev/null -w "status:%{http_code}
"
\
-F "file=@/tmp/test5m.bin" https://你的域名/upload

curl 返回 200 就算通了。如果还是 413,去看 Nginx 的 error.log,里面会有一句非常明确的特征日志:client intended to send too large body,后面跟着具体字节数,对一下这个数就知道是哪一层在拦。另外提醒一句,如果前面还套了 CDN 或者第二层反代,每一层 Nginx 都要放行,只改源站这一层,边缘节点照样把你拦下来。

最后说下 size 0 这个选项:client_max_body_size 0 表示完全不限制请求体,能省事但等于把资源耗尽型攻击的门拆了,生产环境不建议。按业务给每个 location 设不同上限——上传接口 500m、普通 API 5m,才是正确用法。

收尾多说一句这个错误的观感问题:因为浏览器渲染不了 413 页面,用户报障永远只会说“上传失败”或者“网站坏了”,你从报障描述里根本看不出是大小问题。所以凡是有上传功能的站点,建议把 413 做成自定义错误页并在前端提前校验文件大小,用 JS 在提交前拦一道给出明确提示,服务端的这道闸留着兜底就行——体验和防护两头都占。

相关阅读:413 属于接入层的限制类故障。《服务器故障排查总纲:按现象反查的五层定位法》按现象把 502、403、413 这些报错各归其位,出事先翻总纲定层,再进单篇动手。

申请创业报道,分享创业好点子。点击此处,共同探讨创业新机遇!

相关标签
网站服务器

相关文章

  • SSL 证书过期与证书链不完整:openssl s_client 验证与续期监控

    证书过期这事,一旦发生就是全站级别的红色警告。浏览器直接拦截,访客看到的不是你的网站,是一屏吓人的安全提示。更气人的是它完全可以避免——免费证书加自动续期,配好了就再也不用管。Let'sEncrypt的证书有效期是90天,这个短期限是刻意设计的,目的是逼着大家把续期自动化。Certbot是它官方推荐

  • 进程被 OOM Kill:dmesg 定位与关键进程保护

    有一种故障特别难查:服务莫名其妙消失了,应用日志里什么都没留下,没有崩溃堆栈,没有异常退出记录。进程就这么凭空不见。碰到这种情况,十有八九是内核干的——内存不够了,OOMKiller挑中它杀了。OOM的全称是OutofMemory,它是内核的最后手段。Linux默认采用乐观的内存分配策略,进程申请内

  • Linux 磁盘满排查:df 到 du,定位大文件与日志轮转

    网站突然写不进数据,上传图片报失败,数据库开始拒绝写入。登上机器df一看,使用率100%。这种故障不复杂,但它有个特别坑的地方:你按常规思路用du去找大文件,把所有目录的大小加起来,发现远远小于磁盘用量。两个数对不上。对不上通常有三个原因。第一个最常见:文件被删了,但还被某个进程占着。Linux下删

    标签:
    网站服务器
  • MySQL 慢查询拖垮 CPU:processlist 到 pt-query-digest

    服务器CPU突然打满,网站慢得像拨号上网。登上机器一看,MySQL占了大头。这时候最忌讳的是直接重启数据库——重启完负载确实掉了,但过不了多久它还会爬回来,因为那条慢SQL还在那儿等着被执行。第一步是抓现行。SHOWPROCESSLIST能看到此刻正在跑的语句,但默认只显示前100个字符,长SQL会

  • MySQL 1040 Too many connections:连接泄漏定位与上限设定

    网站隔三差五报一句数据库连接失败,刷新两下又好了。这种时好时坏的毛病最烦人,因为它不像宕机那样干脆,你没法守在屏幕前等它出现。等到真去查的时候,现场早没了。MySQL从5.7起max_connections默认就是151,8.0也沿用了这个值。超过之后新连接直接被拒,报ERROR1040。看到这个错

热门排行

信息推荐