📁

【Next.js・nginx】1MB超のアップロードが失敗する理由と対処

に公開

画像をアップロードするリクエストを行うとき、フロントエンド側の設定値が原因で失敗するケースがあったのでまとめておきます。

※私はそのプロジェクトにフロントエンドエンジニアとして関わっており、
フロントエンドではNext.jsを用いていて、サーバーはnginxを用いています。

結論から書くと、以下の2つのデフォルトが1MBのパラメータについて、
設定の変更を行っていないことが原因です。

  • Next.jsのbodysizelimit
  • nginxのclient_max_body_size

bodysizelimitとは?

Next.jsのbodysizelimitとは、Next.jsのサーバーサイドに送信されるリクエストボディの最大サイズを決定するパラメータで、デフォルトは1MBです。

このパラメータが設けられている目的は、サーバーのリソースの大量消費を防ぐためです。
DDoS攻撃(数のコンピュータから標的のサーバーに対して大量のアクセスを送りつけ、サービスを停止させるサイバー攻撃のこと)のリスクを低減させる効果もあります。

ただし、プロフィール画像を設定する機能があり、この画像のファイルサイズについて20MBまで許可するなどの要件がある場合、bodysizelimitが1MBだと、リクエストがbodysizelimitを超えることによってうまくいかなくなるため、設定値を変更してリクエストをうまくいくようにする必要があります。

公式ドキュメントにも記載がありますが、next.config.jsもしくはnext.config.tsで、以下のようにbodysizeLimitを明示的に指定する必要があります。

module.exports = {
  experimental: {
    serverActions: {
      bodySizeLimit: '25mb', // 20MBの画像のアップロードを許可したいので、少し余裕を持たせる
    },
  },
}

client_max_body_sizeとは?

サーバーの大量リソース消費を防ぐためのパラメータを、nginxもNext.jsと同様に持っています。
それが、client_max_body_sizeです。
※Next.jsのbodysizelimitと同様に、デフォルトは1MBです。これに引っかかってリクエストが失敗すると、ステータスコード413(Request Entity Too Large)が返ります。

コンテナの設定ファイルに以下のように設定を追記すればOKです。

client_max_body_size 25m;

Discussion