Специальные символы в имени файла Content-Disposition - PullRequest
29 голосов
/ 01 ноября 2011

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

Я разрабатываю CGI-приложение на C ++, которое доставляет файлы, которые могут содержать в именах специальные символы, такие как
" 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

Chrome

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

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

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

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

Opera

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

  • Несколько склеенных пробелов в именах файлов уменьшены до одного
  • {и} исчезают: " 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 все равно не использует эту кодировку. Так что пока нет решения для символа €.

Кстати: конвертер UTF-8 http://www.rishida.net/tools/conversion/

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

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

РЕДАКТИРОВАТЬ 2:

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

РЕДАКТИРОВАТЬ 3: Длина имени файла

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

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

1 Ответ

11 голосов
/ 01 ноября 2011

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

...