Можно ли предположить, что декодированные процентные коды URI превращаются в UTF-8?

RFC 3986 заявляет, что новая схема URI должна быть закодирована до UTF-8 сначала до кодирования процента. Однако это не относится к предыдущим версиям URI.

Можно ли предположить, что все многобайтовые, закодированные в процентах URI превращаются в кодированную строку UTF-8 после прохождения через urldecode()?

Например, если содержимое $_SERVER['REQUEST_URI'] процитировано в процентах как таковое:

/b%C3%BCch/w%C3%B6rterb%C3%BCch

После передачи этой строки в urldecode() у меня должна быть многобайтовая строка. Но как узнать, в какой кодировке строка? В приведенном выше примере это UTF-8, но безопасно ли всегда так предполагать?

Если это не безопасно предположить, существует ли способ (кроме mb_detect_encoding) для определения кодировки строки? Я проверил заголовки запросов, они, похоже, ничего полезного.

Ответы

Ответ 1

Спасибо за все комментарии и ответы! Я сделал некоторые копания себя после того, как я разместил вопрос и хотел бы записать его здесь как ссылку. Пожалуйста, дайте мне знать, если этот ответ неверен.

Пройдите до конца, чтобы перейти непосредственно к заключению.

Из JETTY Docs по международным символам и кодировке символов, из раздела "Международные символы в URL-адресах", я нашел эти пункты:

Из-за отсутствия стандарта разные броверы использовали разные подходы к кодировке символов. Некоторые используют кодировку страницы, а некоторые используют UTF-8. Некоторые проекты были подготовлены различными органами стандартов, предполагающими, что UTF-8 станет стандартным кодированием. Старые версии причала (например, серия 4.0.x) использовали UTF-8 в качестве значения по умолчанию в ожидании принятого стандарта. В качестве стандарта не ожидалось, jetty-4.1.x вернулась к кодировке по умолчанию ISO-8859-1.

В стандарте HTML организации W3C теперь рекомендуется использовать UTF-8: http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars, и, соответственно, серия jetty-6 использует значение по умолчанию UTF-8.

В связанной спецификации HTML 4.0 действительно есть рекомендация для клиентов для кодирования символов, отличных от ASCII, в UTF-8, прежде чем процентная кодировка, поэтому мы знаем, что это была рекомендация от W3C с HTML 4.0.

Пример, используемый на странице:

<A href="http://foo.org/Håkon">...</A>

В то время как позднее указывается, что для кодирования части фрагмента, он не говорит, что если он также применяется к запросу строка.

Ввод URL-адресов в браузеры

Firefox

Как уже упоминал Пекка, на основе этой ссылки Firefox отправляет ISO-8859-1 кодированный URI еще в 2007 году. Читая ссылку, это похоже на поведение по умолчанию для Firefox < 3.0. я не уверен, что это также относится к Firefox < 3.0 в Mac OS X, поскольку кодировка по умолчанию в Mac - UTF-8.

Я тестировал Firefox 3.6.13 в Windows XP и Firefox 6 как в Windows 7 и Mac OS X. Версия Mac отправляет все UTF-8, так что не о чем беспокоиться.

Firefox 3.6.13 и 6 в окнах кодирует строки запроса в ISO-8859-1 по умолчанию, но когда вы вводите символы, которые не существуют в ISO-8859-1 к строке запроса (α, например), Firefox 3 переключает кодировку всей строки запроса в UTF-8. я довольно уверен, что это одно и то же поведение в более поздних версиях.

В Firefox 3.6.13 и 6 в Windows, которые я тестировал, часть пути URI всегда кодируется как UTF-8.

Если вы введете этот URL-адрес в Firefox 3.6/6 в Windows:

http://localhost/test/ü/ä/index.php?chär=ü

Строка запроса кодируется как ISO-8859-1, но часть "путь" получает кодировку как UTF-8:

http://localhost//test/%C3%BC/%C3%A4/index.php?ch%E4r=%FC

Также следует отметить в соответствии с этим сообщением в блоге, Firefox 3.0 преобразует символ katanaka ア в &#12450; до процентного кодирования Это. Когда я попытался сделать это в Firefox 3.6.13 в строке запроса и путь, символ katanaka правильно закодирован в UTF-8.

Opera

Opera 10.10 на Mac кодирует часть строки запроса в URI в ISO-8859-1, хотя кодировка по умолчанию для Mac OS X UTF-8. Часть "путь" кодируется в UTF-8, как и Firefox.

Если вы попытаетесь ввести греческий алфавит α в строку запроса, он получит отправлен как вопросительный знак.

Такое же поведение проявляется в Opera 11.51 в Windows XP.

Safari

Safari 5.1 на Mac всегда отправляет все как UTF-8. Safari 5.1 в Windows имеет такое же поведение.

Chrome

Версия 13 на Windows кодирует строку запроса и путь как UTF-8. У меня нет Chrome на Mac, но кажется безопасным предположить что Chrome всегда отправляет UTF-8, например Safari.

Internet Explorer

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: я использую IECollection для установки нескольких версий IE в одной машине, поэтому это может быть не естественное поведение IE (кто-нибудь может подтвердить это?).

IE 6, 7 и 8 в Windows XP кодирует "путь" части URI в UTF-8 правильно. Umlauts и греческий алфавит, введенный в запрос Однако строка не получает процентов. Введенная строка запроса в адресную строку, кажется, отправлено в ISO-8859-1, греческий алфавит alpha 'α' в строке запроса транслитерируется в 'a'.

Заключение

Это короткий и неполный, и я не могу гарантировать правильность его, но кажется, что наиболее распространенные кодировки для URI - либо ISO-8859-1, либо UTF-8 (я не знаю, какие восточные азиаты используйте их в качестве кодировки, и для меня слишком сложно использовать и узнайте).

Поскольку это уже рекомендация из HTML 4.0, я думаю, это безопасно предположить, что часть "пути" URI всегда кодируется в UTF-8. Firefox 2.0 все еще может быть вокруг, поэтому вы должны проверить, кодировка также является ISO-8859-1. Если это не UTF-8 или ISO-8859-1, скорее всего это плохой запрос.

Теоретически невозможно правильно определить кодирование строки (см. здесь и здесь). Вы можете догадаться, но вы можете получить неправильный результат. Поэтому не полагайтесь на обнаружение кодировки.

Безопасная многобайтовая маршрутизация

Самый безопасный способ - просто выбрать одну кодировку (UTF-8 - это безопасную ставку) для всего вашего приложения. Затем вы должны:

  • Убедитесь, что все ваши строки закодированы в UTF-8 до используя его для создания вашего URI. Правильно процитируйте свой URI после этого.
  • Убедитесь, что все ваши кодированные URL (GET) формы отправляют свои данные в правильное кодирование. См. этот FAQ от Kore Nordmann для больше информации о том, чтобы ваши формы отправляли правильные кодирование.

Также см. этот отличный ответ от bobince.

После этого у вас не должно возникнуть проблем с анализом URI. Если кодировка не находится в UTF-8, тогда это плохой запрос, и вы может отвечать с 404 или 400 страницами.

Ответ 2

Так как небезопасно предполагать, что в любом случае ( "плохие парни не волнуют" ), вы можете использовать mb_check_encoding для проверки строки UTF-8. UTF имеет структуру, которая с малой вероятностью должна соответствовать строке в другом кодировании.

Ответ 3

Ты не знаешь. Это зависит от человека/кода, сгенерированного URI.