Специальные символы в Content-Disposition filename

Этот поток является дубликатом Как закодировать параметр имени файла заголовка Content-Disposition в HTTP? Но поскольку этот вопрос был задан давно, и по-прежнему нет удовлетворительного ответа (на мой взгляд), я хотел бы снова спросить.

Я разрабатываю CGI-приложение С++, которое предоставляет файлы, которые могут содержать специальные символы в их именах, например " weird # € = {}; filename.txt"

Кажется, нет возможности установить HTTP Content-Dispostion таким образом, чтобы он работал для каждого браузера, например

  • Internet Explorer
  • Firefox
  • Chrome
  • Opera
  • Safari

Я был бы доволен другим решением для каждого браузера.
Вот как далеко я пришел:

Internet Explorer (добавлены двойные кавычки и заменены # и;)

Content-Disposition: attachment; filename="weird %23 € = { } %3B filename.txt"

Firefox (похоже, работают двойные кавычки):

Content-Disposition: attachment; filename="weird # € = { } ; filename.txt"

Другая рабочая альтернатива:

Content-Disposition: attachment; filename*=UTF-8''weird%20%23%20%e2%82%ac%20%3D%20%7B%20%7D%20%3B%20filename.txt

хром

при использовании только двойных кавычек возникают следующие проблемы:

  • = disapears в именах файлов
  • € будет заменен на

но это работает:

Content-Disposition: attachment; filename*=UTF-8''weird%20%23%20%e2%82%ac%20%3D%20%7B%20%7D%20%3B%20filename.txt

Opera

Использование цитат duoble или использование синтаксиса: filename * = UTF-8 ''... вызывает следующие проблемы:

  • Несколько сложенных пространств в именах файлов сводятся к одному
  • {и} disapear: " ab {} cd.txt" → " abcd.txt"
  • имена файлов обрезаются после; в нем: " abc; def.txt" → " abc"

РЕДАКТИРОВАТЬ 2: Это связано с ограничениями длины имени файла. Этот синтаксис работает с Opera:

Content-Disposition: attachment; filename*=UTF-8''weird%20%23%20%e2%82%ac%20%3D%20%7B%20%7D%20%3B%20filename.txt

Safari

  • € будет заменен невидимым символом (с использованием двойных кавычек)

    no solution that prevents that little problem
    

Предложение из другого потока (упомянутого выше) с использованием

Content-Disposition: attachment; filename*=UTF-8''weird%20%23%20%80%20%3D%20%7B%20%7D%20%3B%20filename.txt

не работал у меня. Эвакуационные символы не будут переведены обратно или браузер хочет сохранить файл с именем моего приложения cgi. Это потому, что моя кодировка была неправильной. Я не кодировал в соответствии с RFC 5987. Но Safari не использует эту кодировку в любом случае. Таким образом, никакого решения для символа € пока нет.

BTW: конвертер UTF-8 http://www.rishida.net/tools/conversion/

Я использовал последнюю версию каждого браузера для этих тестов:

  • Firefox 7
  • Internet Explorer 9
  • Chrome 15
  • Opera 11.5
  • Safari 5.1

PS: Я пробовал все специальные символы на моей клавиатуре. Я использовал в этой теме только те, которые делали проблемы.

EDIT:

Я также попробовал имя файла со всеми специальными символами на моей клавиатуре (возможно в имени файла), и это не сработало так же, как с тестовой строкой выше:

Полная тестовая строка:

0 ! § $ % & ( ) = ` ´ { }    [ ] ² ³ @ € µ ^ ° ~ + ' # - _ . , ; ü ä ö ß 9.jpg

Кодированная тестовая строка:

0%20%21%20%C2%A7%20%24%20%25%20%26%20%28%20%29%20%3D%20%60%20%C2%B4%20%7B%20%7D%20%20%20%20%5B%20%5D%20%C2%B2%20%C2%B3%20%40%20%E2%82%AC%20%C2%B5%20%5E%20%C2%B0%20~%20%2B%20%27%20%23%20-%20_%20.%20%2C%20%3B%20%C3%BC%20%C3%A4%20%C3%B6%20%C3%9F%209.jpg

Используя этот метод:

Content-Disposition: attachment; filename*=UTF-8''0%20%21%20%C2%A7%20%24%20%25%20%26%20%28%20%29%20%3D%20%60%20%C2%B4%20%7B%20%7D%20%20%20%20%5B%20%5D%20%C2%B2%20%C2%B3%20%40%20%E2%82%AC%20%C2%B5%20%5E%20%C2%B0%20~%20%2B%20%27%20%23%20-%20_%20.%20%2C%20%3B%20%C3%BC%20%C3%A4%20%C3%B6%20%C3%9F%209.jpg

У меня были следующие результаты:

  • Firefox работает
  • Chrome работает
  • IE: $% и() = `'{} [] ² ³ @€ μ ^ ° ~ +' # - _.,; ü ä ö ß 9.jpg(удалены первые 6 символов). РЕДАКТИРОВАТЬ 2: Это из-за ограничений длины имени браузера. Он начинает обрезать имя файла с начала строки. Я не углублялся в это, но похоже, что нормальные имена файлов могут содержать около 200 символов, а имена файлов со многими escape-последовательностями еще больше, но меньше 250. Но это нормально.
  • Опера: 0! § $% и() = `'[] ² ³ @€ μ ^ ° ~ +' # - _.,; ü ä ö ß 9.jpg(не хватает некоторых символов, как и раньше). EDIT 2: Я сократил тестовую строку, потому что я подозревал, что длина файла "проблемы" с Opera, как есть в IE, и там тоже работала.
  • Safari не работает с этим синтаксисом. Это было исключено.

ИЗМЕНИТЬ 2:

Статус до сих пор заключается в том, что синтаксис имя_файла * = UTF-8''filname escape-последовательность " работает с каждым браузером, кроме Safari. И единственный символ, который заменяется на Safari, Думаю, я смогу жить с этим. Спасибо!

ИЗМЕНИТЬ 3: Длина имени файла

Я заметил некоторые проблемы с длиной файла.

  • Internet Explorer: имена файлов могут составлять 147 символов. Если строка не содержит escape-последовательностей, то длина файла. Если это имя файла может отличаться. Полученное имя файла короче 147 символов. Но он отличается. Я использовал 2 escape-последовательности, и имя файла сократило 5 символов, и я использовал много escape-последовательностей, а имя файла сократило onyl 2 символа. Я не мог найти здесь правила.
  • У других браузеров, похоже, нет этой проблемы. Они сохранили бы файл, если файловая система сможет его обработать. Я попробовал, например, 250 символов, и браузеры сказали, что мне нужно уменьшить имя файла (Chrome), или они сделали это, сократив его до 220 (Opera) или 210 (Firefox) символов. Тем не менее Opera отключает файл. Safari попытался сохранить это длинное имя файла и не сохранил его и записал "-1" в списке загрузки как имя файла.

Ответ 1

Firefox, MSIE (начиная с версии 9), поддержка Opera, Konq и Chrome; MSIE8 и Safari не поддерживают; другая поддержка неизвестна - кодировка, определенная в RFC 5987.

Обратите внимание, что в

  Content-Disposition: attachment; filename*=UTF-8''weird%20%23%20%80%20%3D%20%7B%20%7D%20%3B%20filename.txt

у вас есть кодировка для символа евро неправильно; это кодовая точка unicode не% 80, исправление этого должно заставить ее работать везде, кроме Safari (правильная кодировка составляет% e2% 82% ac).

Тестовый пример:

http://greenbytes.de/tech/tc2231/#attwithfn2231utf8