跳到内容

如何正确配置Nginx的client_max_body_size | 上传限制问题排查

分类:Nginx·服务器配置
本文目前仅提供日文版本。我们正在进行翻译工作。

在 Nginx 中实现文件上传时,「小文件可以上传,但上传大文件时出现 413 错误」的问题非常常见。原因几乎总是 <code>client_max_body_size</code> 配置不足。然而,仅修复 Nginx 配置通常无法解决问题,需要全面理解 PHP 的 <code>upload_max_filesize</code> 和 <code>post_max_size</code>,以及超时设置。本文系统地解释了与上传限制相关的所有配置项。

client_max_body_size 10m 5 MB POST 10 MB POST 20 MB POST nginx limit: 10 MB 200 OK 200 OK 413 Too Large 超过限制的请求在到达上游之前被拒绝为 413
图:根据 client_max_body_size 进行允许/拒绝判定

client_max_body_size的默认值和作用

Nginx有一个<code>client_max_body_size</code>指令,用于限制来自客户端的请求体的最大大小。默认值为<code>1m</code>(1 MiB)。超过此限制的请求会立即被拒绝,返回<code>413 Request Entity Too Large</code>错误。

由于默认值仅为 1m,即使上传单张图片或 PDF 也会很快达到限制。在实际生产环境中,需要根据用途适当提高这个值。

配置位置:http / server / location 的差异

<code>client_max_body_size</code> 可以在 Nginx 的任何配置级别(http / server / location)设置。更具体的范围设置优先。

# http ブロック(全サーバー共通)
http {
    client_max_body_size 10m;

    server {
        listen 80;
        server_name example.com;

        # server ブロック(このバーチャルホスト全体)
        client_max_body_size 50m;

        location /upload {
            # location ブロック(このパスのみ)
            # より大きなファイルを許可したい場合
            client_max_body_size 200m;

            proxy_pass http://app;
        }

        location /api {
            # APIエンドポイントはデフォルト(1m)のままにする例
            client_max_body_size 1m;
        }
    }
}

仅为上传专用端点设置较大值,而保持其他端点较小是安全最佳实践。可以指定 <code>0</code> 以实现无限制,但这会增加 DoS 攻击风险,不推荐。

413 Request Entity Too Large错误的原因和解决方案

我们将整理413错误的原因和处理方法。

原因 检查项 解决方案
Nginx 限制超出 nginx.conf 中的 <code>client_max_body_size</code> 提高值
PHP限制超出 php.ini 中的 <code>upload_max_filesize</code> 提高值
整个 POST 正文超过限制 php.ini 中的 <code>post_max_size</code> 设置为大于 upload_max_filesize
反向代理限制 上游 Nginx 或负载均衡器配置 检查每个阶段的代理

修改 Nginx 配置后,必须重新加载。

# 設定の文法チェック
nginx -t

# 設定のリロード(サービス停止なし)
nginx -s reload

# または systemd 経由
systemctl reload nginx

与PHP的upload_max_filesize / post_max_size的关系

仅提高 Nginx 的 <code>client_max_body_size</code> 是不够的。如果后端是 PHP,PHP 级别也有独立的限制。只有当这 3 个设置都设置为适当的值时,上传才会成功。

; php.ini の設定
; 1ファイルあたりの上限
upload_max_filesize = 100M

; POSTリクエスト全体の上限(upload_max_filesize より大きくする)
; multipart/form-data のオーバーヘッド分を見込んで多めに設定
post_max_size = 110M

; メモリ上限(post_max_size より大きくする)
memory_limit = 256M

; アップロード処理の実行時間(大容量ファイル用に延ばす)
max_execution_time = 300
max_input_time = 300

重要配置值之间的关系如下。

  • client_max_body_size(Nginx)post_max_size(PHP)upload_max_filesize(PHP)
  • 如果 Nginx 拒绝请求,处理永远无法到达 PHP
  • <code>post_max_size</code> 是整个 POST 请求体的大小限制,包括多个文件上传和非文件表单字段

proxy_read_timeout / proxy_send_timeout 的重要性

上传大文件时,超时设置也很重要。默认的 <code>proxy_read_timeout</code> 为 60 秒,如果上传耗时过长,处理将被中断。

location /upload {
    client_max_body_size 500m;

    proxy_pass http://app_backend;

    # バックエンドからのレスポンス待機時間
    # 大容量ファイルの処理には長めに設定
    proxy_read_timeout 600s;

    # クライアントへのデータ送信待機時間
    proxy_send_timeout 600s;

    # バックエンドへの接続タイムアウト
    proxy_connect_timeout 60s;

    # クライアントのリクエストボディ受信タイムアウト
    # 2回の連続した読み取り操作の間の時間
    client_body_timeout 120s;
}

建议为上传端点和常规 API 端点设置不同的超时值。

Docker 中的配置(nginx.conf 挂载)

在 Docker 环境中,自定义 nginx.conf 或 conf.d 文件被挂载到容器中以应用配置。

# Dockerfile でのカスタム設定追加
FROM nginx:alpine

# カスタム設定ファイルをコピー
COPY ./nginx/conf.d/upload.conf /etc/nginx/conf.d/upload.conf

# デフォルト設定を完全に置き換える場合
# COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
# docker-compose.yml でのボリュームマウント
version: '3.8'
services:
  nginx:
    image: nginx:alpine
    volumes:
      # ディレクトリごとマウント(変更が即反映される)
      - ./nginx/conf.d:/etc/nginx/conf.d
      # または特定ファイルだけマウント
      # - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
    ports:
      - "80:80"
# nginx/conf.d/upload.conf
server {
    listen 80;
    server_name localhost;

    # グローバルのアップロード上限
    client_max_body_size 100m;

    location / {
        proxy_pass http://app:9000;
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
    }

    location /upload {
        client_max_body_size 500m;
        proxy_pass http://app:9000;
        proxy_read_timeout 600s;
        proxy_send_timeout 600s;
    }
}

配置确认命令

要检查当前Nginx配置中<code>client_max_body_size</code>的值,使用<code>nginx -T</code>展开所有设置后再进行grep搜索会很方便。

# 全設定を展開して client_max_body_size を検索
nginx -T | grep -i body_size

# 出力例:
#   client_max_body_size 1m;   ← デフォルト(http ブロック)
#   client_max_body_size 100m; ← カスタム設定(server ブロック)

# 設定ファイルのパスも確認
nginx -T | grep "# configuration"

# 特定の設定ファイルだけチェック
nginx -t -c /etc/nginx/nginx.conf

# 現在読み込まれている設定のダンプ
nginx -T 2>/dev/null | grep -A1 "client_max"

常见配置错误及解决方法

  • <strong>单位错误</strong>:<code>client_max_body_size 100</code> 默认为字节。必须指定单位,例如 <code>100m</code>
  • <strong>层级疏漏</strong>:你以为在 location 块中覆盖,但上层的 server 块或 http 块正在生效
  • <strong>忘记重新加载</strong>:修改配置文件后,如果不运行 <code>nginx -s reload</code>,更改将不会生效
  • <strong>多个 server 块</strong>:通过 include 加载的其他 conf.d 文件产生冲突
  • <strong>与 PHP 的不匹配</strong>:即使提高 Nginx 限制,如果 PHP 的 <code>upload_max_filesize</code> 仍然较低,可能会出现 413 之外的错误

本文中可用的测试文件(免费)

  • → <a href="/ja/files/threshold/" class="text-primary-600 dark:text-primary-400 hover:underline">边界值测试文件列表</a> — 通过 client_max_body_size 配置值前后的文件重现错误
  • → <a href="/ja/files/images/png/" class="text-primary-600 dark:text-primary-400 hover:underline">PNG 测试图像列表</a> — 使用各种大小的 PNG 图像验证 Nginx 限制

相关文章

  • → <a href="/ja/blog/how-to-test-upload-limit/" class="text-primary-600 dark:text-primary-400 hover:underline">如何正确测试文件上传限制</a>
  • → <a href="/ja/blog/multipart-form-data-overhead/" class="text-primary-600 dark:text-primary-400 hover:underline">准确计算 multipart/form-data 的开销</a>
  • → <a href="/ja/blog/mb-vs-mib-file-size/" class="text-primary-600 dark:text-primary-400 hover:underline">MB 和 MiB 的区别|文件大小单位的正确理解</a>

常见问题

Nginx的client_max_body_size默认值是多少?

默认值为 1m(1 兆字节)。超过此值的请求将导致 413 Request Entity Too Large 错误。

client_max_body_size应该在哪里配置?

可以在 <code>http</code>、<code>server</code> 或 <code>location</code> 块中设置。如果只想更改特定端点,请在 <code>location</code> 块中编写。

Nginx 和 PHP 上传设置之间的关系是什么?

Nginx在请求到达PHP之前用client_max_body_size进行检查。同时需要配置PHP端的upload_max_filesize和post_max_size。