2013-02-01 2 views
2

Я написал функцию, которая генерирует некоторый файл csv на лету и отправляет пользователю для загрузки.flask send_file и unicode filename: broken in IE

код ниже:

@app.route('/survey/<survey_id>/report') 
def survey_downloadreport(survey_id): 
    survey, bsonobj = survey_get(survey_id) 
    resps = response_get_multi(survey_id) 

    fields = ["_id", "sid", "date", "user_ip"] 
    fields.extend(survey.formfields)  

    csvf = StringIO.StringIO() 
    wr = csv.DictWriter(csvf, fields, encoding = 'cp949') 
    wr.writerow(dict(zip(fields, fields))) 
    for resp in resps : 
     wr.writerow(resp) 

    csvf.seek(0) 

    now = datetime.datetime.now() 
    report_name = survey.name + "(" + \ 
        now.strftime("%Y-%m-%d-%H:%M:%S") +\ 
        ")" + ".csv" 

    report_name = report_name.encode("utf-8") 



    return send_file(csvf, 
       as_attachment = True, 
       attachment_filename = report_name) 

, как вы можете видеть, имя файла преобразуется из Юникода в строку и в UTF-8 (точнее, они в корейских букв.)

проблема в том, что имена файлов полностью нарушены при просмотре страницы в IE (без проблем в хроме).

Кажется, что заголовок должен быть отредактирован для соответствия правилам синтаксического разбора для разных браузеров, но я не знаю, как это сделать в колбе.

ответ

3

Попробуйте добавить

mimetype = 'text/csv; charset=x-EBCDIC-KoreanAndKoreanExtended' 

к send_file.

+0

не работает .. все еще получить непонятное имя файла при загрузке dialougue. – thkang

+0

@thkang: см. Мое редактирование. Если вы кодируете CSV как cp949 (почему вы не используете UTF-8??), То параметр charset, вероятно, должен быть x-EBCDIC-KoreanAndKoreanExtended, а не UTF-8. –

+0

для cp949, потому что корейские окна немного неудобны; насколько я знаю, содержимое файла хранится в cp949. Я тестировал cp949 и utf-8, и только строковые значения cp949 были превосходными. :(В любом случае, после кодирования 'report_name' в cp949 и добавления вышеуказанной кодировки в send_file, все идеально. – thkang

2

Использование Content-Disposition: attachment; filename="..." для установки имени загружаемого файла - это то, что делает Flask send_file - не является надежным для символов, отличных от ASCII.

До тех пор, пока в библиотеке werkzeug.http не поддерживается поддержка RFC 5987, и во всех браузерах, на которые вы хотите настроить таргетинг, это невозможно устранить.

В то же время, более надежный метод кросс-браузер поставить UTF-8-URL-закодирован файла в задней части URI, когда вы делаете ссылки на него, а именно:

IRI path: /survey/1/report/안녕.csv 
URI path: /survey/1/report/%ec%95%88%eb%85%95.csv 

См. How to encode UTF8 filename for HTTP headers? (Python, Django) для фона.

 Смежные вопросы

  • Нет связанных вопросов^_^