「クライアントからファイルを受け取り、サーバからもファイルを返す」という処理を1回のユーザ操作で実現したく調べた結果、fetch api、blobを使って実装したのでサンプルを記載しておきます。
サーバ側はDjangoです。
HTML側
sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
<title>fetch sample</title>
</head>
<body>
<form name="upload_form" onsubmit="myFetch()" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<input id="upload_file" type="file" name="file">
<input type="submit" value="送信">
</form>
<script type="text/javascript">
function myFetch(event) {
// HTMLでの送信をキャンセル これをしないとページがリフレッシュされる
event.preventDefault();
let fd = new FormData( document.getElementById('upload_form') );
fetch("/hogeURL", {
// ファイルを送信
method: "POST",
body: fd
}).then(response => response.blob())
.then(myBlob => {
// サーバからのレスポンスが完了
// サーバ処理でエラーが起きてもここに来る
console.log('完了');
// 内部的にBlobオブジェクトに対するリンクを生成&クリックしてダウンロード
let a = document.createElement("a");
a.style = "display: none";
a.href = URL.createObjectURL(myBlob);
a.download = 'ダウンロード用ファイル名';
document.body.appendChild(a);
a.click();
}).catch(function(error) {
console.log('エラー:', error.message);
});
}
</script>
</body>
</html>
サーバ側
views.py
def upload(request):
# サーバ内での処理の例 アップロードされたファイルを保存
req_file = request.FILES['file']
destination = open('ファイルを保存するパス', 'wb')
for chunk in req_file.chunks():
destination.write(chunk)
# ファイルを返却
response = HttpResponse(open('返却するファイルのパス', 'rb').read(), content_type='ファイルのMIME type')
response['Content-Disposition'] = 'attachment; filename="返却時のファイルの名称"'
return response