質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.11%

【nginx】 1MB(デフォルト)以上のファイルが送信できません。Request Entity Too Large【django】

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 961

score 14

問題+知りたいこと

Ubuntu + nginx + django + Gunicorn + Ajaxで画像ファイルを送信するウェブアプリを開発していますが、1MB以上の画像ファイルを送信しようとすると、Request Entity Too Large のエラーが出てしまいます。

この問題について調査した結果、/etc/nginx/nginx.conf にて下記のように設定すると改善するとわかりました。

http{
  ****省略***
  server{
    client_max_body_size    100M;
    client_body_buffer_size 100M;
    listen                  80;
    server_name             localhost;
    root                    /var/www/html/<djangoのproject名>;
  }
}

この設定を施し、下記コマンドを実行して設定ファイルの更新処理をしましたが、動きませんでした。

sudo systemctl reload nginx
sudo systemctl restart <djangoのproject名> nginx

1MBより大きい画像ファイルをアップロードする場合、どのようにすれば良いのか、ご教授願います。

環境

Ubuntu 18.04.4 LTS
django 3.0.6
nginx version: nginx/1.14.0 (Ubuntu)
gunicorn (version 20.0.4)

エラーログ

path:/var/log/nginx/error.log

2020/05/28 09:08:45 [error] 10093#10093: *11 client intended to send too large body: 6373261 bytes, client: 192.168.11.12, server: 192.168.11.100, request: "POST /webapp/ HTTP/1.1", host: "192.168.11.100", referrer: "http://192.168.11.100/webapp/"

Ajaxコード

function ajax_fileupload(){
    var fd new FormData($("#main_form").get(0));
    $.ajax({
        url: "", 
        type: "POST",
        data: fd, 
        processData: false,
        contentType: false,
        dataType: 'json'
    })
    .done( function( data , status , xhr){
     //アップロード成功時の処理、送信成功したファイルの名前が返ってくる
    }
*******以下略*******
}

djangoのviews.py

*****以上略(各種必要なライブラリのimport)*******

class WebappView(View):
  def get(self, request, *args, **kwargs):
    #GET時の処理
  def post(self, request, *args, **kwargs):
        #ファイルアップロード処理
        if request.FILES:

            try:
                if "file_1" in request.FILES:
                    uploaded_file       = request.FILES["file_1"]

                _,file_ext          = os.path.splitext(uploaded_file.name)

                uploaded_filename   = timezone.now().strftime("%Y%m%d%H%M%S%f") + file_ext

                #ファイル名は"年月日時分秒マイクロ秒.拡張子"とする
                file_name           = default_storage.save(uploaded_filename , uploaded_file)

            except Exception as e:
                print("アップロードエラー:{}".format(e))

            return JsonResponse({"file_name":file_name})

フォーム内の画像を、POST文のAjaxを利用して送信。ファイルを/var/www/<djangoのproject名>/media/に保存する仕組みです。保存が成功したら、ファイル名がAjaxによって返却されます。

補足

  1. この1MB以上のファイルが送信できない問題は、manage.pyの仮想サーバーでは発生しませんでした。前述の本番環境にデプロイした途端、この問題が発生しました。
  2. djangoのモデル、テンプレート等には容量制限の指定は行っておりません。 
  3. 通信はhttp通信、サーバーはローカルネットワークにあります。

【以下参考にしたサイト・書籍】
https://hacknote.jp/archives/27367/
https://stackoverflow.com/questions/36994828/413-request-entity-too-large-nginx-django
現場で使える Django の教科書《基礎編》
現場で使える Django の教科書《実践編》

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

自己解決しました。しかし、これは最適解ではないかもしれません。

<before> 

http{
  ****省略***
  server{
    client_max_body_size    100M;
    client_body_buffer_size 100M;
    listen                  80;
    server_name             localhost;
    root                    /var/www/html/<djangoのproject名>;
  }
}




<after> 

http{
  ****省略***

  #↓以下を追加
  client_max_body_size    100M;

  server{
    client_max_body_size    100M;
    client_body_buffer_size 100M;
    listen                  80;
    server_name             localhost;
    root                    /var/www/html/<djangoのproject名>;
  }
}

おそらく、サーバーごとの指定で100MBを上限としても、デフォルトの指定が1MBになっているため、それが優先されてしまうのだと思われます。
server以下に10M指定をしたとしても、デフォルトの100Mが働き、100MBまでのファイルが通ってしまいます。


補足

server_nameをサーバーのIPアドレスに当たる、192.168.11.100にしたり、http://192.168.11.100にしてもserverで指定したclient_max_body_sizeの指定が適応されませんでした。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/05/29 00:27

    server{
    server_name localhost;
    }
    に記載で効いてないならば、そこの設定が使われてないということではないでしょうか。ほかにserver{ }設定しているところがあるのではないでしょうか。

    http://localhost/***** でアクセスしたときに、該当のserver{ }設定が適用されますが、それ以外のときは別な個所のserver{ }設定が適用されるはずです。

    キャンセル

  • 2020/05/29 11:36

    補足を加えました。サーバーのIPアドレスも直に指定してみましたが、うまくいきませんでした。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.11%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る