目的
- リクエストに対してマルチバイトファイル名でファイルダウンロードさせる。
httpでファイルダウンロード
- httpの決まり事として、ファイルをダウンロードさせたいときは、レスポンスに Content-Dispositionヘッダを含めれば良いことになっています。
Content-Disposition: attachment; filename="filename.txt"
Djangoの記述
- 下記で期待通り動きます。ただし、ファイル名がascii文字の場合です。
from django.http import HttpResponse
def index(request):
content = 'body1'
response = HttpResponse(content, content_type='text/plain')
response['Content-Disposition'] = 'attachment; filename="filename.txt"'
return response
マルチバイト文字の場合
response['Content-Disposition'] = 'attachment; filename="ファイル.txt"'
- ヘッダは下記のようになります。UTF8-MIME-Base64ぽい。
- 実際、email.header.Headerを使ってエンコードしているようです。
Content-Disposition: =?utf-8?b?YXR0YWNobWVudDsgZmlsZW5hbWU9IuODleOCoeOCpOODqy50eHQi?=
- これは正しい挙動なのか調べていませんが、とりあえず手元のWebブラウザではファイルをダウンロードするように解釈してくれないようです。
対応方法
- ファイル名部分だけをURLエンコードしてセットします。
import urllib.parse
response['Content-Disposition'] = 'attachment; filename="{fn}"'.format(fn=urllib.parse.quote("ファイル.txt"))
- ヘッダは下記のようになり、Webブラウザも期待通り、ファイルダウンロードレスポンスとして動作してくれます。
Content-Disposition: attachment; filename="%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.txt"