Nginx配置上传文件大小限制的完整指南

11 次阅读

Nginx 默认对客户端请求体大小有一定限制,当用户通过网页上传较大的图片、视频、压缩包或其他文件时,如果没有调整相关配置,就可能出现 413 Request Entity Too Large 错误。这个问题通常并不复杂,但实际项目中还需要考虑 Nginx、应用服务器以及上传组件之间的限制是否一致。

一、Nginx上传文件大小限制由什么参数控制

Nginx 主要通过 client_max_body_size 指令限制客户端请求体的最大大小。

典型配置如下:

Nginx
http {
    client_max_body_size 100M;
}

表示允许客户端发送的请求体最大为 100 MB。

这个参数不仅影响文件上传,也会影响其他 HTTP 请求体,例如:

  • 图片上传

  • 视频上传

  • ZIP、RAR 等压缩文件上传

  • JSON 大请求

  • 表单提交

  • 文件批量上传

如果请求体超过 client_max_body_size 设置的大小,Nginx 通常会直接返回 HTTP 413 状态码,请求不会继续转发到后端应用。

二、client_max_body_size的配置级别

client_max_body_size 可以配置在不同层级,主要包括 http、server 和 location。

1. 配置在http层

Nginx
http {
    client_max_body_size 100M;

    server {
        listen 80;
        server_name example.com;
    }
}

这种方式会对该 http 配置块中的服务器产生统一影响,适合整个 Nginx 实例都采用相同上传限制的场景。

2. 配置在server层

Nginx
server {
    listen 80;
    server_name example.com;

    client_max_body_size 100M;
}

这种配置只针对当前虚拟主机。

如果一台服务器运行多个网站,而不同网站对上传文件大小的需求不同,使用 server 层通常更加合理。

3. 配置在location层

Nginx
server {
    listen 80;
    server_name example.com;

    location /upload/ {
        client_max_body_size 500M;
    }
}

这种方式可以针对特定 URL 设置上传限制。

例如普通接口只允许上传 10 MB 文件,而 /upload/ 专门用于视频上传,可以单独设置为 500 MB:

Nginx
server {
    listen 80;
    server_name example.com;

    client_max_body_size 10M;

    location /upload/ {
        client_max_body_size 500M;
    }
}

这种配置粒度更细,也更适合生产环境。

三、Nginx允许上传指定大小的文件

假设项目要求允许上传最大 50 MB 的文件,可以直接设置:

Nginx
server {
    listen 80;
    server_name example.com;

    client_max_body_size 50M;
}

修改配置后,需要检查 Nginx 配置文件是否存在语法错误:

Bash
nginx -t

如果看到类似:

syntax is ok
test is successful

说明配置检查通过。

然后重新加载配置:

Bash
nginx -s reload

或者使用 systemd:

Bash
systemctl reload nginx

如果修改的是 /etc/nginx/nginx.conf,也可以根据实际环境使用:

Bash
systemctl restart nginx

不过对于线上服务而言,单纯修改配置后执行 reload 通常更加平滑,可以减少不必要的连接中断。

四、常见文件大小单位

client_max_body_size 支持使用字节以及常见的大小单位。

例如:

Nginx
client_max_body_size 10M;

表示最大 10 MB。

常见写法包括:

Nginx
client_max_body_size 1M;
client_max_body_size 20M;
client_max_body_size 500M;
client_max_body_size 1G;

也可以直接指定字节数,例如:

Nginx
client_max_body_size 10485760;

不过实际维护配置时,使用 M 或 G 更直观。

需要注意,文件大小限制是实际请求体大小限制,并不等于简单意义上的“文件名长度”或者“单个表单字段长度”。

五、为什么修改后仍然出现413错误

这是上传问题中最常见的情况之一。

例如 Nginx 已经设置:

Nginx
client_max_body_size 200M;

但上传 100 MB 文件时仍然失败,那么问题未必来自 Nginx。

实际请求链路可能是:

浏览器
   ↓
CDN / 负载均衡
   ↓
Nginx
   ↓
Java / PHP / Node.js / Python
   ↓
应用框架

其中任何一层都可能存在请求体大小限制。

因此,解决上传文件过大问题时,需要逐层检查。

Nginx层

检查:

Nginx
client_max_body_size 200M;

PHP项目

如果后端使用 PHP,还需要关注 php.ini:

INI
upload_max_filesize = 200M
post_max_size = 210M

修改后通常需要重新加载 PHP-FPM。

这里需要注意,post_max_size 应该能够容纳整个 POST 请求,而不仅仅是文件本身,因此通常会设置得比 upload_max_filesize 稍大一些。

Java项目

Spring Boot 项目通常还需要关注 multipart 上传限制,例如:

properties
spring.servlet.multipart.max-file-size=200MB
spring.servlet.multipart.max-request-size=210MB

具体参数还会受到 Spring Boot 版本和应用实现方式影响。

Node.js项目

如果使用 Express、Koa 或其他 Node.js 框架,还需要检查所使用的 body parser、multipart 上传中间件等组件的限制。

因此,Nginx 放宽限制并不意味着后端一定能够接收同样大小的文件。

六、Nginx配置为0是什么意思

某些场景会看到:

Nginx
client_max_body_size 0;

这个配置表示不检查客户端请求体大小。

也就是说,从 Nginx 的 client_max_body_size 这一层来看,请求体大小不受该指令限制。

例如:

Nginx
server {
    listen 80;
    server_name example.com;

    client_max_body_size 0;
}

但这并不意味着整个系统可以无限上传文件。

后端应用、反向代理、网关、CDN、磁盘空间以及网络连接都可能继续限制上传大小。

生产环境一般不建议为了简单解决 413 问题就直接设置:

Nginx
client_max_body_size 0;

更合理的做法是根据业务需求设置明确的上限。

七、针对不同接口设置不同上传限制

大型项目通常不应该让所有 API 使用同一个上传限制。

例如:

Nginx
server {
    listen 80;
    server_name example.com;

    client_max_body_size 10M;

    location /api/image/upload {
        client_max_body_size 20M;
    }

    location /api/video/upload {
        client_max_body_size 1G;
    }
}

这样可以实现:

普通请求       10 MB
图片上传       20 MB
视频上传       1 GB

相比直接在 http 层设置一个非常大的值,这种方式更容易控制风险。

八、Nginx反向代理场景下的上传配置

如果 Nginx 作为反向代理服务器,可以这样配置:

Nginx
server {
    listen 80;
    server_name example.com;

    client_max_body_size 100M;

    location /api/ {
        proxy_pass http://127.0.0.1:8080;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

这里的 client_max_body_size 控制客户端发送到 Nginx 的请求体大小。

而:

Nginx
proxy_pass http://127.0.0.1:8080;

负责将请求转发给后端。

两者是不同的配置功能,不要把 proxy_pass 和文件大小限制混为一谈。

九、上传大文件时还要关注代理缓冲

对于大文件上传,除了:

Nginx
client_max_body_size

还可能需要根据业务场景关注请求体读取、代理缓冲以及临时文件等行为。

例如:

Nginx
location /upload/ {
    client_max_body_size 1G;
    proxy_request_buffering off;
    proxy_pass http://127.0.0.1:8080;
}

proxy_request_buffering off 可以让 Nginx 不再按照默认方式完整缓冲客户端请求体后再向上游发送,而是更加直接地向后端转发请求体。

对于大文件上传、流式上传等场景,这可能有助于降低 Nginx 本地临时存储带来的压力。

不过该参数并不是“上传大文件必须配置”的选项。是否关闭请求缓冲,应结合后端应用处理能力、网络情况以及服务器资源进行测试。

十、Nginx临时文件与磁盘空间问题

处理大型上传请求时,服务器磁盘空间也是一个容易忽视的问题。

某些代理请求场景下,Nginx 可能需要使用临时文件保存请求数据。

可以通过配置类似:

Nginx
client_body_temp_path /var/cache/nginx/client_temp;

指定客户端请求体临时文件的位置。

例如:

Nginx
http {
    client_max_body_size 500M;
    client_body_temp_path /var/cache/nginx/client_temp;

    server {
        listen 80;
        server_name example.com;
    }
}

如果服务器磁盘空间不足,即使 client_max_body_size 设置得足够大,上传仍然可能失败。

因此对于 500 MB、1 GB 甚至更大的文件上传,应同时检查:

Bash
df -h

确认磁盘容量。

如果使用容器部署,还需要特别注意 Docker 容器所在磁盘、挂载目录以及临时目录的空间。

十一、如何排查413 Request Entity Too Large

当浏览器提示:

413 Request Entity Too Large

可以按照以下顺序排查。

第一步:检查Nginx配置

搜索:

Bash
grep -R "client_max_body_size" /etc/nginx/

查看实际生效配置。

也可以执行:

Bash
nginx -T

查看 Nginx 当前完整配置。

相比只查看某一个配置文件,nginx -T 更适合排查 include 文件导致的配置覆盖问题。

第二步:检查配置语法

Bash
nginx -t

确保配置没有语法错误。

第三步:重新加载Nginx

Bash
systemctl reload nginx

或者:

Bash
nginx -s reload

第四步:确认请求实际命中了哪个server

如果服务器存在多个:

Nginx
server {}

配置块,修改了错误的虚拟主机配置,就可能导致设置看似正确,但实际请求仍然受到其他配置限制。

重点检查:

Nginx
listen
server_name
location

以及默认服务器配置。

第五步:检查后端限制

如果 Nginx 已经允许 200 MB,但上传仍失败,就需要检查后端应用。

特别是 PHP、Spring Boot、Node.js、Django、Flask 等框架,都可能拥有独立的请求体或文件大小限制。

第六步:检查中间层

如果架构为:

用户
 ↓
CDN
 ↓
负载均衡
 ↓
Nginx
 ↓
应用

还需要检查 CDN、API 网关和负载均衡器是否设置了请求体大小限制。

十二、修改Nginx配置后不生效的常见原因

1. 修改了错误的配置文件

Nginx 可能通过:

Nginx
include /etc/nginx/conf.d/*.conf;

或者其他 include 指令加载多个配置文件。

因此不要只凭经验判断配置文件位置,建议使用:

Bash
nginx -T

确认最终加载的配置。

2. 没有reload或restart

修改配置文件并不会自动让已经运行的 Nginx 进程使用新配置。

需要执行:

Bash
nginx -t
nginx -s reload

3. location配置覆盖了预期设置

例如:

Nginx
server {
    client_max_body_size 100M;

    location /upload/ {
        client_max_body_size 20M;
    }
}

访问 /upload/ 时,最终限制并不是 100 MB,而是由更具体的 location 配置决定。

因此排查时要重点关注配置继承关系和匹配到的 location。

4. 前面还有其他代理

如果用户访问的是 CDN 或云负载均衡提供的域名,而不是直接访问 Nginx,那么请求可能在到达 Nginx 之前就被限制。

十三、生产环境如何合理设置上传大小

上传大小不建议简单设置成一个非常大的数字。

例如业务只需要上传图片,最大文件大小是 20 MB,那么可以:

Nginx
location /upload/image/ {
    client_max_body_size 20M;
}

如果视频业务需要最大 2 GB,则针对视频接口单独配置:

Nginx
location /upload/video/ {
    client_max_body_size 2G;
}

这样既满足业务需求,也避免普通接口接受过大的请求。

同时建议在应用层再次校验文件大小,因为 Nginx 的限制属于基础设施层控制,业务系统仍然需要对文件类型、文件大小、文件内容和权限进行验证。

十四、大文件上传的进一步优化思路

当文件从几十 MB 增长到数百 MB、数 GB 后,仅仅修改:

Nginx
client_max_body_size

通常已经不是完整解决方案。

可以考虑使用分片上传。

例如将一个 1 GB 文件拆分成多个 10 MB 分片:

1GB文件
 ├── chunk-001
 ├── chunk-002
 ├── chunk-003
 ├── ...
 └── chunk-100

客户端分别上传分片,服务器收到全部分片后再进行合并。

这种方式具有几个明显优势:

  • 单次请求体更小

  • 网络中断后可以重新上传失败分片

  • 支持断点续传

  • 更适合大文件

  • 可以降低单个 HTTP 请求的压力

对于超大型文件,还可以考虑让浏览器直接上传到对象存储,例如通过预签名 URL 让客户端绕过业务服务器上传文件。

此时 Nginx 主要负责普通 API 请求,而不再承担所有大文件数据流量,可以降低应用服务器和反向代理的带宽压力。

十五、一个完整的Nginx上传配置示例

下面给出一个比较常见的生产配置思路:

Nginx
server {
    listen 80;
    server_name example.com;

    # 普通请求默认最大 10MB
    client_max_body_size 10M;

    location / {
        proxy_pass http://127.0.0.1:8080;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # 图片上传最大 20MB
    location /upload/image/ {
        client_max_body_size 20M;

        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # 视频上传最大 1GB
    location /upload/video/ {
        client_max_body_size 1G;
        proxy_request_buffering off;

        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

修改后执行:

Bash
nginx -t
systemctl reload nginx

然后分别使用不同大小的文件测试上传接口,确认实际行为符合预期。

十六、配置Nginx上传大小时的注意事项

第一,不要把 client_max_body_size 和后端文件上传限制混为一谈。Nginx 放行并不代表后端一定能够接收。

第二,不建议无条件使用:

Nginx
client_max_body_size 0;

明确设置业务需要的上限通常更加合理。

第三,大文件上传需要关注服务器磁盘、网络带宽、超时、代理缓冲以及后端处理能力。

第四,如果存在 CDN、负载均衡或 API 网关,需要确认整条请求链路上的限制。

第五,修改配置后不要忘记:

Bash
nginx -t

然后:

Bash
systemctl reload nginx

第六,生产环境应当结合应用层进行二次校验。对于上传文件,还应该根据业务需求校验文件类型、扩展名、MIME 类型和实际文件内容,避免仅依赖文件名判断文件格式。

第七,如果业务长期需要上传数百 MB 或数 GB 的文件,应优先评估分片上传、断点续传和对象存储方案,而不是无限增大 Nginx 请求体限制。

掌握 client_max_body_size 的配置方式后,Nginx 文件上传限制问题通常可以快速定位。对于普通网站,将参数配置在 server 或特定 location 中即可;对于大型项目,则应该从浏览器、CDN、网关、Nginx、后端应用到存储系统整体考虑,确保每一层的上传策略相互匹配。