Header content disposition attachment filename

Web applications that want to force a resource to be downloaded rather than directly rendered in a Web browser issue a Content-Disposition header in the HTTP response of the form:

Content-Disposition: attachment; filename=FILENAME

The filename parameter can be used to suggest a name for the file into which the resource is downloaded by the browser. RFC 2183 (Content-Disposition), however, states in section 2.3 (The Filename Parameter) that the file name can only use US-ASCII characters:

Current [RFC 2045] grammar restricts parameter values (and hence Content-Disposition filenames) to US-ASCII. We recognize the great desirability of allowing arbitrary character sets in filenames, but it is beyond the scope of this document to define the necessary mechanisms.

There is empirical evidence, nevertheless, that most popular Web browsers today seem to permit non-US-ASCII characters yet (for the lack of a standard) disagree on the encoding scheme and character set specification of the file name. Question is then, what are the various schemes and encodings employed by the popular browsers if the file name “naïvefile” (without quotes and where the third letter is U+00EF) needed to be encoded into the Content-Disposition header?

For the purpose of this question, popular browsers being:

  • Firefox
  • Internet Explorer
  • Safari
  • Google Chrome
  • Opera

18 Answers 18

There is discussion of this, including links to browser testing and backwards compatibility, in the proposed RFC 5987, "Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters."

RFC 2183 indicates that such headers should be encoded according to RFC 2184, which was obsoleted by RFC 2231, covered by the draft RFC above.

I know this is an old post but it is still very relevant. I have found that modern browsers support rfc5987, which allows utf-8 encoding, percentage encoded (url-encoded). Then Naïve file.txt becomes:

Safari (5) does not support this. Instead you should use the Safari standard of writing the file name directly in your utf-8 encoded header:

IE8 and older don’t support it either and you need to use the IE standard of utf-8 encoding, percentage encoded:

In ASP.Net I use the following code:

I tested the above using IE7, IE8, IE9, Chrome 13, Opera 11, FF5, Safari 5.

Update November 2013:

Here is the code I currently use. I still have to support IE8, so I cannot get rid of the first part. It turns out that browsers on Android use the built in Android download manager and it cannot reliably parse file names in the standard way.

The above now tested in IE7-11, Chrome 32, Opera 12, FF25, Safari 6, using this filename for download: 你好abcABCæøåÆØÅäöüïëêîâéíáóúýñ½§!#¤%&()=`@£$€<[]>+´¨^

On IE7 it works for some characters but not all. But who cares about IE7 nowadays?

Читайте также:  Как войти в реестр windows 7

This is the function I use to generate safe file names for Android. Note that I don’t know which characters are supported on Android but that I have tested that these work for sure:

@TomZ: I tested in IE7 and IE8 and it turned out that I did not need to escape apostrophe (‘). Do you have an example where it fails?

@Dave Van den Eynde: Combining the two file names on one line as according to RFC6266 works except for Android and IE7+8 and I have updated the code to reflect this. Thank you for the suggestion.

@Thilo: No idea about GoodReader or any other non-browser. You might have some luck using the Android approach.

@Alex Zhukovskiy: I don’t know why but as discussed on Connect it doesn’t seem to work terribly well.

веб-приложения, которые хотят заставить ресурс быть загрузить, а не вынесено в веб-браузере проблема a Content-Disposition заголовок в HTTP-ответ вида:

Content-Disposition: attachment; filename=FILENAME

на может использоваться для указания имени файла, в который браузер загружает ресурс. RFC 2183 (Content-Disposition), однако, говорится в 2.3 (Имя Параметр), что имя файла может использовать только символы US-ASCII:

текущая [RFC 2045] грамматика ограничивает значения параметров (и, следовательно, Назначение содержимого файлов) в США-ASCII. Мы признаем великое желательность разрешения произвольных наборы символов в именах файлов, но это за рамками настоящего документа определите необходимые механизмы.

есть эмпирические данные, тем не менее, что большинство популярных веб-браузеров сегодня, кажется, разрешить символы, отличные от US-ASCII, но (из-за отсутствия стандарта) не согласны со схемой кодирования и спецификацией набора символов имени файла. Вопрос в том, какие различные схемы и кодировки используются популярными браузерами, если имя файла "naïvefile" (без кавычек и где третья буква U+00EF) необходимо закодировать в заголовок Content-Disposition?

для целей этого вопроса,популярные браузеры существо:

  • в Firefox
  • Internet Explorer
  • сафари
  • Google Chrome
  • Опера

17 ответов

существует обсуждение этого, включая ссылки на тестирование браузера и обратную совместимость, в предложенном RFC 5987, " набор символов и кодировка языка для параметров поля заголовка протокола передачи гипертекста (HTTP)."

RFC 2183 указывает на то, что такие заголовки должны быть закодированы в соответствии с RFC 2184, который был заменен на RFC 2231, охватывается проектом RFC выше.

Я знаю, это старый пост, но он по-прежнему очень актуальна. Я обнаружил, что современные браузеры поддерживают rfc5987, который позволяет кодировать utf-8, процент кодируется (url-кодируется). Тогда наивный файл.txt становится:

Safari (5) не поддерживает это. Вместо этого вы должны использовать стандарт Safari для записи имени файла непосредственно в кодированном заголовке utf-8:

IE8 и старше не поддерживают его, и вам нужно использовать стандарт IE кодировки utf-8, в процентах закодировано:

In ASP.Net я использую следующий код:

я протестировал выше, используя IE7, IE8, IE9, Chrome 13, Opera 11, FF5, Safari 5.

обновление ноября 2013 года:

Читайте также:  Денежные переводы между физическими лицами

вот код, который я сейчас использую. Мне все еще нужно поддерживать IE8, поэтому я не могу избавиться от первой части. Оказывается, браузеры на Android используют встроенный менеджер загрузки Android и не могут надежно анализировать имена файлов в стандарте путь.

вышеуказанное теперь протестировано в IE7-11, Chrome 32, Opera 12, FF25, Safari 6, используя это имя файла для загрузки: §abcabcæøåæøåäöüïëêîâéíáóúýñ½§!#¤%&()=`@£$€<[]>+^

на IE7 он работает для некоторых символов, но не для всех. Но кто заботится о IE7 в настоящее время?

это функция, которую я использую для создания безопасных имен файлов для Android. Обратите внимание, что я не знаю, какие символы поддерживаются на Android, но я проверил, что они работают для конечно:

@TomZ: я тестировал в IE7 и IE8, и оказалось, что мне не нужно избегать Апострофа (‘). У вас есть пример где это не удается?

@Dave Van den Eynde: объединение двух имен файлов в одной строке, как в соответствии с RFC6266 работает, за исключением Android и IE7+8, и я обновил код, чтобы отразить это. Спасибо за предложение.

@Thilo: нет идеи о GoodReader или любом другом не-браузере. Возможно, Вам повезет с помощью Android подход.

@Alex Zhukovskiy: я не знаю, почему, но как обсуждалось на подключиться кажется, это не очень хорошо работает.

нет совместимого способа кодирования имен, отличных от ASCII, в Content-Disposition . совместимость браузера беспорядок.

The теоретически правильный синтаксис для использования UTF-8 в Content-Disposition очень странно: filename*=UTF-8»foo%c3%a4 (да, это звездочка, и никаких кавычек, кроме пустой одинарной кавычки посередине)

этот заголовок является своего рода-не совсем стандартным (спецификация HTTP/1.1 подтверждает существование, но не требует, чтобы клиенты поддерживали его).

существует простая и очень надежная альтернатива:используйте URL, содержащий имя файла, которое вы хотите.

когда имя после последней косой черты является тем, что вы хотите, вам не нужны дополнительные заголовки!

этот трюк работает:

и если ваш сервер поддерживает перезапись URL (например, mod_rewrite в Apache), то вы можете полностью скрыть скрипт часть.

символы в URL-адресах должны быть в UTF-8, urlencoded байт за байтом:

RFC 6266 описывает "использование поля заголовка Content-Disposition в протоколе передачи гипертекста (HTTP)". Цитата из этого:

в " filename* " параметр (4.3), используя определенную кодировку в [ RFC5987], позволяет серверу передавать символы вне ISO-8859-1 набор символов, а также дополнительно укажите язык в употреблении.

этот пример совпадает с приведенным выше, но добавляет " filename" параметр совместимости с агентами пользователей, не реализующими RFC 5987:

Примечание: те агенты пользователей, которые не поддерживают RFC 5987 кодировка игнорировать " filename* " когда это происходит после " filename ".

на Приложение D существует также длинный список предложений по повышению совместимости. Он также указывает на сайт, который сравнивает реализаций. Текущие тесты all-pass, подходящие для общих имен файлов, включают:

  • attwithisofnplain: простое имя файла ISO-8859-1 с двойными кавычками и без кодировки. Для этого требуется имя файла, которое является ISO-8859-1 и не содержит знаков процента, по крайней мере, не перед шестнадцатеричными цифрами.
  • attfnboth: два параметра в порядке, описанном выше. Должен работать для большинства имен файлов в большинстве браузеров, хотя IE8 будет использовать " filename параметр".
Читайте также:  Tp link td w8960n настройка на русском

это RFC 5987 в свою очередь, ссылается RFC 2231, который описывает фактический формат. 2231 в основном для почты, и 5987 говорит нам, какие части могут использоваться для HTTP-заголовков. Не путайте это с заголовками MIME используется внутри multipart/form-data адресу http тело, который регулируется RFC 2388 (4.4 в частности) и HTML 5 черновик.

Добрый день, уважаемы хабра-юзеры.

Возникла следующая проблема. Имеется веб-приложение (клиент на js, сервер на php) и некое файловое хранилище. Чтобы скачать файл из хранилища, клиентская часть веб-приложения шлет запрос на серверную, там выполняется бизнес логика (проверка прав доступа и т.д.), если все ок, то отдается ссылка на файл. Затем клиентская часть делает редирект на эту ссылку. На сервере файлового хранилища стоит nginx, который и отдает файлы. Имена у файлов представляют собой набор символов без смыслового содержания (просто GUID), что не очень нравилось пользователям. Они хотели бы, чтобы при скачивании у файла было такое же имя, как у соответствующей ему сущности в веб-приложении. Поскольку переименовывать файлы очень не хотелось бы по некоторым причинам, было придумано следующее:

1. При формировании ссылки в серверной части веб-приложения к ней цепляется GET-параметр, в котором содержится приемлемое для пользователя имя файла.
2. В конфиге nginx при отдаче файла этот параметр подставляется в заголовок Content-Disposition.
(add_header Content-Disposition ‘attachment;Filename=$args’;)

Проблемы начались с подстановкой в Content-Disposition русского текста.
Во-первых, firefox при редиректе на хранилище делает urlencode ссылки. И nginx в Content-Disposition подставляет закодированную строку. Соответственно firefox предлагает сохранить файл также под закодированным именем.
Во-вторых, даже если в Content-Disposition будет незакодированная строка, но в UTF-8 с кириллицей, то IE ничего знать не хочет о том, что это UTF-8. Интерпретирует его как cp1251 и имя файла получается с кракозябрами.

В общем, данная схема нормально работает только в хроме. Если я не ошибаюсь, то с проблемой номер 1 (urlencode) можно справиться, если пересобрать nginx из исходников, включив в него модуль ngx_set_misc. Тогда в конфиге nginx можно будет с помощью set_unescape_uri сделать urldecode для имени файла перед тем как вставлять его в заголовок Content-Disposition. Но к такому варианту хотелось бы прибегать в последнюю очередь.
А как решить проблему с IE — вообще не знаю.

В общем, я в тупике. Был бы очень благодарен за совет, может быть есть гораздо более простой способ решения моей задачи, а я его в упор не вижу.