Прежде всего, я почти уверен, что это не дубликат, потому что я изучал эту тему в течение достаточно долгого времени, как в StackOverflow, так и в других местах. Подобные вопросы задавались, но ни на один из них не был получен удовлетворительный ответ.
Связанные (но не идентичные) вопросы из прошлого:
- Браузер Android Chrome без необходимости переименовывает имена и типы загруженных файлов
- Как кодировать параметр имени файла заголовка Content-Disposition в HTTP?
Я также полностью осведомлен о mod_rewrite
трюках, которые делают его совершенно ненужным для жонглирования именами файлов в заголовках HTTP. Но допустим, что это не вариант.
Большинство современных браузеров (IE9+, Firefox, Chrome) поддерживают RFC2231/5987 при загрузке файлов с кодом, отличным от ASCII. символов в своих именах. В этих случаях следующий PHP-код работает как шарм:
header("Content-Disposition: attachment; " .
"filename*=UTF-8''" . rawurlencode($filename));
IE ‹= 8 не понимает RFC2231/5987, но в большинстве случаев работает следующий код. Поскольку каждый браузер пытался в какой-то степени эмулировать IE, это работает и во многих других браузерах, таких как Firefox.
header("Content-Disposition: attachment; " .
'filename="' . rawurlencode($filename) . '"');
Между тем, Chrome ‹ 11 и Safari ‹ 6, похоже, предпочитают следующее, несмотря на то, что они размещают не-ASCII-символы непосредственно в заголовке.
header("Content-Disposition: attachment; filename=" . $filename);
Все идет нормально.
Но все рушится, когда дело доходит до браузерного приложения Android по умолчанию. (До сих пор я тестировал это в Gingerbread, Ice Cream Sandwich и Jelly Bean.)
Если вы дадите ему стандартную обработку RFC2231/5987, браузер по умолчанию полностью проигнорирует его и попытается угадать имя файла из последней части URL-адреса.
Если вы дадите ему обычную нестандартную (IE ‹ = 8) обработку, либо браузер по умолчанию попытается интерпретировать имя файла как ISO-8859-1, что приведет к неразборчивой мешанине символов, либо он молча отбрасывает все символы, отличные от ASCII. . Точное поведение различается между версиями, но в любом случае ясно, что браузер Android по умолчанию также не предназначен для поддержки формата rawurlencode().
То же самое произойдет, если вы поместите необработанное имя файла в заголовок.
Обычно это не проблема со сторонними браузерами, такими как Firefox для Android, Dolphin Browser и Boat Browser. Браузерное приложение по умолчанию — единственное, которое постоянно не понимает имена файлов UTF-8.
Возможно, это было окончательно исправлено в последней версии Android, или, возможно, это будет исправлено в следующей версии. Но это не мой вопрос. Мне нужно, чтобы это работало на существующих устройствах, а есть еще миллионы устройств Gingerbread и ICS.
Я прочитал отчеты об ошибках, я прочитал жалобы, я прочитал почти все, что можно прочитать об этой проблеме. До сих пор мне не удалось найти какую-либо схему кодирования, которая действительно работает.
Если кто-нибудь знает, как закодировать имя файла, отличное от ASCII** (например, файла파일ファイル名.jpg
) в Content-Disposition
**заголовке, чтобы браузер Android по умолчанию распознал его, поделитесь им! Мне все равно, насколько он хакерский или нестандартный. Меня не волнует, нужно ли его настраивать для каждой версии Android.
Обновлять
К сожалению, до сих пор я не получил никакого ответа, который действительно решает проблему, упомянутую выше. Таким образом, награда истекает невостребованной. Пожалуйста, не отвечайте, если вы действительно не знаете, как кодировать неевропейские имена файлов на разных языках таким образом, чтобы они распознавались браузером Android до ICS, или если у вас есть веские доказательства того, что это невозможно.