Специальные символы в Content-Disposition имя_файла

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

Я разрабатываю приложение C ++ 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 (двойные кавычки, похоже, работают. Ничего более to do):

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 '' ... приводит к следующим проблемам:

  • Несколько склеенных вместе пробелов в именах файлов сокращаются до одного
  • {и} 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

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

     нет решения, которое предотвращает эту небольшую проблему 
     

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

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
  • Chrome 15
  • Opera 11.5
  • Safari 5.1

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

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

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

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

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 (по-прежнему отсутствуют некоторые символы). РЕДАКТИРОВАТЬ 2: Я сократил свою тестовую строку, потому что подозревал, что длина имени файла «проблемы» с Opera, как и с IE, и там тоже сработало.
  • Safari не поддерживает этот синтаксис. Это было исключено.

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

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

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

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

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

30
задан Community 23 May 2017 в 11:54
поделиться