Этот поток является дубликатом Как закодировать параметр имени файла заголовка 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
Предложение из другой ветки (упоминалось выше) с использованием
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» в списке загрузки в качестве имени файла.