Можно ли предположить, что декодированные URI, закодированные в процентах, превращаются в UTF-8? - PullRequest
15 голосов
/ 10 октября 2011

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) обнаружить кодировку строки? Я проверил заголовки запросов, они, кажется, не имеют ничего полезного.

Ответы [ 3 ]

3 голосов
/ 11 октября 2011

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

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

Из документов JETTY по международным символам и кодированию символов ,из раздела «Международные символы в URL» я нашел следующие абзацы:

Из-за отсутствия стандарта разные браузеры по-разному подходили к используемой кодировке символов.Некоторые используют кодировку страницы, а некоторые используют UTF-8.Некоторые проекты были подготовлены различными органами по стандартизации, предполагая, что UTF-8 станет стандартной кодировкой.В старых версиях Jetty (например, серии 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 отправляет URI в кодировке ISO-8859-1 еще в 2007 году. Считая ссылку, это поведение по умолчанию для Firefox <3.0.Я не уверен, применимо ли это к Firefox <3.0 в Mac OS X, поскольку кодировка <a href="http://en.wikipedia.org/wiki/Mac_OS_Roman" rel="nofollow noreferrer"> по умолчанию в Mac - UTF-8 .

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

Firefox 3.6.13 и 6 в Windows кодирует строки запроса в 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 преобразует символ катанака ア в &#12450; перед процентным кодированием.Когда я попытался сделать это в Firefox 3.6.13 в строке запроса и пути, символ катанака был правильно закодирован в UTF-8.

Opera

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

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

То же самоеOpera демонстрирует поведение 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.Умлауты и греческий алфавит, введенные в строку запроса, не кодируются в процентах.Строка запроса, введенная в адресную строку, кажется, отправляется в ISO-8859-1, буквенный алфавит греческого алфавита 'α' в строке запроса транслитерируется в '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 - самая безопасная ставка) для вашейвсе приложение.Затем вы должны:

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

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

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

0 голосов
/ 11 октября 2011

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

0 голосов
/ 11 октября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...