目的
リクエストに対してマルチバイトファイル名でファイルダウンロードさせる。
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"