接口上传文件时如果突然出现413 Request Entity Too Large,通常不是后端业务代码的问题,而是Nginx在请求进入应用之前就拒绝了请求体。Nginx通过client_max_body_size指令限制客户端请求体的最大体积,默认值是1m。也就是说,任何超过1MB的POST请求体都会在Nginx层被拦截,后端应用甚至看不到这次请求。这个限制不仅影响文件上传,也会影响任何带有较大JSON、XML或表单数据的POST请求。

理解这个指令之前,需要先弄清楚Nginx处理请求体的流程。Nginx接收到带请求体的请求后,会根据Content-Length头判断请求体大小,再与client_max_body_size比较。如果超过限制,Nginx直接返回413状态码,默认错误页内容为413 Request Entity Too Large。这个判断发生在读取请求体之前,因此对大文件请求的拒绝速度非常快,不会消耗后端资源。对于上传场景来说,这个机制能保护后端服务不被超大请求拖垮,但也容易成为配置遗漏点。
默认值与作用域:放在哪里才生效
client_max_body_size可以在http、server、location三个层级中使用,作用范围依次缩小,内层配置会覆盖外层配置。如果整个站点都需要允许大文件上传,可以把指令放在http块中。如果只有某个域名或某个接口需要放开限制,建议优先放在对应的server或location块中,避免全局放大请求体限制带来安全隐患。
最基本的配置写法如下,允许请求体最大为20MB:
http {
client_max_body_size 20m;
server {
listen 80;
server_name ipipp.com;
location /upload {
proxy_pass http://127.0.0.1:8080;
}
}
}
如果只想针对上传接口放开限制,其他路径继续使用默认1MB限制,可以只在location中配置:
server {
listen 80;
server_name ipipp.com;
location /upload {
client_max_body_size 50m;
proxy_pass http://127.0.0.1:8080;
}
location /api {
client_max_body_size 2m;
proxy_pass http://127.0.0.1:8080;
}
}
将client_max_body_size设置为0表示不限制请求体大小,这种配置一般不建议直接用于公网环境,因为攻击者可以构造超大请求消耗带宽和磁盘IO。如果确实需要接收非常大的文件,更推荐设置一个明确的业务上限,例如200m或500m,同时配合client_body_timeout、proxy_read_timeout等参数控制请求时长。
修改后不生效的常见原因与验证方法
修改完Nginx配置后需要执行nginx -t测试配置语法,再通过nginx -s reload重新加载配置。如果配置写在错误的上下文中,或者server块中使用了多个location,需要确认实际匹配的location是否包含client_max_body_size指令。Nginx的location匹配遵循一定的优先级规则,普通前缀匹配、正则匹配和精确匹配的结果可能和直觉不同,配置生效的location也许不是你预期的那个。
验证配置是否生效最直接的方法是使用curl发送一个超过限制的文件。先生成一个5MB的临时文件,然后请求上传接口:
dd if=/dev/zero of=/tmp/testfile bs=1M count=5 curl -F "file=@/tmp/testfile" http://ipipp.com/upload
如果配置限制为20m,这个5MB请求会正常通过。把限制改成2m后重新测试,应该会看到413 Request Entity Too Large响应。判断后端是否收到请求也很重要,因为有时Nginx虽然放行,但后端容器、应用框架或反向代理还设置了更小的限制。此时前端看到的可能是502、500或其他状态码,容易被误认为Nginx配置没有生效。
另外需要检查Nginx是否在多层代理之后。典型架构是负载均衡器、网关、应用层Nginx依次转发请求,每一层都可能设置了client_max_body_size。如果只有最外层放开,内层仍然使用默认1m,大文件请求会在内层被拦截。排查时可以逐层查看access日志和错误日志,或者分别在每一层的location中使用不同的返回头进行标记,快速定位是哪一层返回了413。
与后端参数、缓冲区和超时时间配合
只调整Nginx的client_max_body_size并不能保证大文件上传一定成功。Nginx在接收请求体时还会使用client_body_buffer_size控制缓冲区大小,超出部分会写入临时文件。默认情况下临时文件存放在client_body_temp_path指定的目录,通常是Nginx安装目录下的client_body_temp文件夹。如果该目录没有写权限或者磁盘空间不足,上传也可能失败。对于普通文件上传,缓冲区默认值一般够用,但当请求体很大或磁盘较慢时,可以适当调整缓冲区大小和临时目录位置。
如果后端使用PHP处理上传,还需要同步修改php.ini中的upload_max_filesize和post_max_size,而且post_max_size应大于等于upload_max_filesize。例如Nginx允许20MB,但PHP默认只允许2MB,实际仍然无法上传超过2MB的文件。PHP配置示例为:
upload_max_filesize = 20M post_max_size = 25M max_execution_time = 300 max_input_time = 300
Java应用如果使用Spring Boot,需要检查servlet容器的multipart配置。以Spring Boot 2.x为例,可以通过application.properties设置:
spring.servlet.multipart.max-file-size=20MB spring.servlet.multipart.max-request-size=25MB
Node.js、Go等自建服务则需要检查应用本身是否对请求体大小做了限制。很多框架默认会限制表单或JSON体积,例如Express的json中间件和urlencoded中间件都有limit参数,Koa、Fastify等框架也有类似机制。上传链路中任意一环的限制都会导致请求失败,因此在排查时要同时关注Nginx、反向代理、后端运行时和业务代码四层。
client_max_body_size调整完成并确认后端参数一致后,建议用真实文件做一次端到端测试。除了检查HTTP状态码,还要确认文件内容完整。可以使用文件校验值对比原文件和服务器落盘后的文件,避免因为临时目录空间不足或缓冲区问题造成文件截断。对于大文件上传,还可以考虑使用分片上传、断点续传等方案,这样既能绕过单次请求体积限制,也能提升用户体验。
最后需要提醒,放开client_max_body_size会增加服务器被恶意请求攻击的风险。特别是公开注册上传接口,攻击者可能利用超大请求占满带宽或磁盘。合理的做法是只对需要上传的location放开限制,同时设置限流、请求超时和身份鉴权,必要时在Nginx前面接入WAF或使用对象存储直传方案,由客户端直接上传到对象存储,避免大文件流经Nginx和应用服务器。
Nginxclient_max_body_size文件上传限制修改时间:2026-09-19 11:35:02