朕喜技术(ZhenxiJS)
2026.09.08
1 分钟阅读

Nginx + PHP 上传大文件报 413 Request Entity Too Large:client_max_body_size 与 upload_max_filesize 双层限制详解

关键词: Nginx 413, client_max_body_size, upload_max_filesize, post_max_size, PHP-FPM, 文件上传, 大文件上传失败, multipart/form-data, Request Entity Too Large

问题背景

Nginx + PHP-FPM 的 Web 应用支持用户上传文件,但上传超过 1MB 的文件总是失败,返回 413 Request Entity Too Large。小文件(<1MB)正常。检查服务器磁盘空间充足、Nginx/PHP 运行正常,日志里也没有 PHP 报错——因为请求根本到不了 PHP。

复现步骤

# 1. 在 scenario/2026-09-08-0800 下启动环境
docker compose up -d --build

# 2. 生成一个 3MB 测试文件并 curl 上传
head -c 3145728 /dev/urandom > /tmp/big.bin
curl -i -F "file=@/tmp/big.bin" http://localhost:8080/upload.php

# 复现输出:HTTP/1.1 413 Request Entity Too Large

根本原因

这是一个 Nginx + PHP 双层上传限制 叠加导致的经典问题。请求从浏览器到文件落盘,要经过两层"关卡":

第 1 层:Nginx client_max_body_size(默认 1m)

Nginx 在 http/server/location 级别有 client_max_body_size 指令,默认值为 1m。当客户端 POST 的请求体(body)超过该值时,Nginx 直接返回 413 Request Entity Too Large,不会把请求转发给后端 PHP-FPM。

配置文件中的问题代码:

# nginx/default.conf
client_max_body_size 1m;   # ← 这就是 413 的来源

第 2 层:PHP 自己的上传限制

就算把 Nginx 放行,PHP 也有两把锁:

  • upload_max_filesize:单个上传文件的最大字节数(默认 2M)
  • post_max_size:整个 POST body 的最大字节数(默认 8M,必须 ≥ upload_max_filesize)

当 Nginx 放行但 PHP 超限时,PHP 拒绝文件,$_FILES['file']['error'] = 1(UPLOAD_ERR_INI_SIZE)。

解决办法

第 1 步:调大 Nginx client_max_body_size

编辑 nginx/default.conf:

client_max_body_size 20m;   # 按需调整,如 20m/50m/100m

第 2 步:调大 PHP 上传限制

编辑 PHP 配置(本环境为 php/php.ini 通过 volume 覆盖):

upload_max_filesize = 20M
post_max_size = 25M        # 必须 ≥ upload_max_filesize,且要容纳整个 multipart body

第 3 步:重启服务让配置生效

docker compose restart nginx php
# 或生产环境:nginx -s reload && systemctl restart php-fpm

验证

# 生成 3MB 测试文件并上传
head -c 3145728 /dev/urandom > /tmp/big.bin
curl -F "file=@/tmp/big.bin" http://localhost:8080/upload.php

# 修复前:HTTP 413 Request Entity Too Large
# 修复后:HTTP 200,响应 "上传成功!"

经验与避坑

  1. 413 的第一反应查 Nginx:client_max_body_size 默认仅 1m,比大多数人的想象要小得多。
  2. 两层都要调:只改 Nginx 不改 PHP,请求过了 Nginx 会在 PHP 层被拒(表现为 $_FILES['file']['error'] = 1);只改 PHP 不改 Nginx,请求在 Nginx 就被拦,PHP 根本收不到。
  3. post_max_size 必须 ≥ upload_max_filesize:post_max_size 限制的是整个 POST body,除文件内容外还有 multipart boundary、表单字段等额外开销,需要留出余量。
  4. 改完配置必须重启/重载:Nginx 的 client_max_body_size 需要 nginx -s reload,PHP 配置需要重启 PHP-FPM,两者都不会热加载。
  5. 如何快速区分是哪层在拦:
    • Nginx 返回 413(HTML 错误页来自 Nginx)→ 第 1 层 Nginx
    • Nginx 返回 200 但页面提示"超过 PHP 限制"/$_FILES['file']['error'] = 1 → 第 2 层 PHP
    • 检查响应头 Server: nginx/... 可确认是 Nginx 层的 413
  6. Docker 场景注意:配置文件通过 volume 挂载时,docker compose restart 即可生效;如果配置文件在镜像构建时 COPY 进去,则需 docker compose up -d --build 重建。

相关文件

  • 问题配置:nginx/default.conf、php/php.ini
  • 上传处理:app/www/upload.php
  • 验证脚本:check.sh
  • 复现脚本:reproduce.sh
  • 完整操作记录:scenario/2026-09-08-0800/SOLUTION.md

版权声明

本文为博主原创文章,遵循 CC BY-NC-SA 4.0 许可协议。 转载请注明出处:http://localhost/blogs/2026-09-08-0806-nginx-php-413-upload-size-limit

分享这篇文章