前提・実現したいこと
Djangoで作成したサイトでバイナリファイルをアップロードし、サーバ上に保存したい。
- 環境情報
CentOS 6.7
Python2.7
Django1.7
発生している問題・エラーメッセージ
ファイルサイズ6MB程度までは正常にアップロードできるが、7MB以上になると以下のエラーが発生する。
※サイズは目安です。正確なしきい値は不明です。
UnreadablePostError: Apache/mod_wsgi request data read error: The timeout specified has expired.,
おおよそ20秒でエラーが発生していたので、メッセージどおりのタイムアウトを疑ったのですが、20秒という数値がタイムアウトとして思い当たる設定がないのと、6MB程度のファイルをアップロードしたときは22秒程度はかかって正常終了したことから、それ以外の要素がある可能性があります。
該当のソースコード
以下のフォームでファイルを選択します。
HTML
1<form id="upload_files_form" name="upload_files_form" action="/upload/" target="upload_dummy" method="POST" enctype="multipart/form-data"> 2 <input type="hidden" name="csrfmiddlewaretoken" value="0xKA93pAPKYZAU5dlV6jiP6bl14ThtHt"> 3 <label class="required">データファイルアップロード</label> 4 <input id="upload_files" name="files" type="file" multiple=""> 5</form>
onchangeイベントを付与してuploadします。
javascript
1 $(document).on("change", "#upload_files", function() { 2 // ファイル名は取得できないのでformにinput領域として追加する 3 var filenameElement = document.createElement('input'); 4 var filenames = ""; 5 for (var i = 0; i < document.getElementById('upload_files').files.length; i++ ) { 6 filenames += document.getElementById('upload_files').files[i].name + "/"; 7 } 8 filenameElement.setAttribute('value', filenames); 9 filenameElement.setAttribute('name','filenames'); 10 filenameElement.setAttribute('hidden',null); 11 document.forms.upload_files_form.appendChild(filenameElement); 12 13 // ファイルをアップロードする 14 var XHR = new XMLHttpRequest(); 15 var FD = new FormData(document.forms.upload_files_form); 16 XHR.open("POST", "/upload/"); 17 XHR.send(FD); 18 }); 19
Viewで受け取りファイルを出力します。
python
1@csrf_exempt 2def upload(request): 3 filenames_str = request.POST['filenames'].encode('utf-8') 4 files = request.FILES.getlist('files') 5 6 if (not (os.path.exists(UPLOAD_DIR_ROOT))): 7 os.mkdir(UPLOAD_DIR_ROOT) 8 9 filenames = filenames_str.split("/") 10 11 for i in range(0, len(files)): 12 filepath = os.path.join(UPLOAD_DIR_ROOT, filenames[i]) 13 file = open(filepath, "wb") 14 for chunk in files[i].chunks(): 15 file.write(chunk) 16 return HttpResponse("")
試したこと
Apacheのタイムアウト設定を確認し、明示的に300秒に設定。
DjangoのSettings.pyにファイルサイズの上限を100MBに設定。
設定のキーワードがググったところ2種類見つかったので、2つ設定。
MAX_UPLOAD_SIZE = 104857600
DATA_UPLOAD_MAX_MEMORY_SIZE = 104857600
ファイルサイズに関して調査して上記のとおりでした。
バイナリ、テキスト両方試しましたが違いはありませんでした。
補足情報(FW/ツールのバージョンなど)
CentOS 6.7
Python2.7
Django1.7
同じコードを以下の環境で実行したときは問題なく動作しました。
ubuntu server 16.04
Python 3.7
Django 2.1
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/04/26 06:07
2019/04/26 06:12