PHP UTF-кодированная строка URL - PullRequest
4 голосов
/ 30 июля 2010

Когда я набираю в Firefox (в адресной строке) URL-адрес, такой как http://www.example.com/?query=Траливали,, он автоматически кодируется в http://www.example.com/?query=%D2%F0%E0%EB%E8%E2%E0%EB%E8.

Но URL типа http://www.example.com/#ajax_call?query=Траливали не конвертируется.

Другие браузеры, такие как IE8, вообще не конвертируют запросы.

Вопрос: как определить (в PHP), закодирован ли запрос? Как его расшифровать?

Я пробовал:

  1. $ str = iconv ('cp1251', 'utf-8', urldecode ($ str));

  2. $ str = utf8_decode (urldecode ($ str));

  3. $ str = (urldecode ($ str));

  4. много функций от http://php.net/manual/en/function.urldecode.php Ничего не работает.

Тест:

$ str = $ _GET ['str'];

d ('% D2% F0% E0% EB% E8% E2% E0% EB% E8' == urldecode ('% D2% F0% E0% EB% E8% E2% E0% EB% E8') );

d ('% D2% F0% E0% EB% E8% E2% E0% EB% E8' == $ str);

d ('Траливали' == $ str);

д (urldecode ($ ул)); * * тысяча сорок-семь

д (utf8_decode (urldecode ($ ул)));

!!! d ('% D2% F0% E0% EB% E8% E2% E0% EB% E8' == urlencode ($ str)); !!!

Возвращает:

[ложь] [ложный] [ложный] ???? [Верно]

Какое-то решение: http://www.example.com/Траливали/ - отправить запрос как часть URL и выполнить синтаксический анализ с mod_rewrite.

Ответы [ 7 ]

6 голосов
/ 30 июля 2010

Он не преобразуется как имеющий часть query URL после того, как фрагмент недействителен.

RFC 3986 определяет URI, состоящий из следующих частей:

     foo://example.com:8042/over/there?name=ferret#nose
     \_/   \______________/\_________/ \_________/ \__/
      |           |            |            |        |
   scheme     authority       path        query   fragment

Порядок не может быть изменен.Следовательно,

URL1: http://www.example.com/?query=Траливали#ajax_call

будет обрабатываться правильно, а

URL2: http://www.example.com/#ajax_call?query=Траливали

- нет.Если мы посмотрим на URL2, IE на самом деле правильно обрабатывает URL, обнаружив фрагмент как #ajax_call?query=Траливали без запроса.Фрагмент всегда последний и никогда не отправляются на сервер .

IE правильно закодирует компонент запроса URL1, поскольку он обнаружит его как запрос.

Что касается декодирования в PHP, %D2 и т.п. автоматически декодируются в переменной $_GET['query'].Причина, по которой переменная $_GET была заполнена неправильно, заключалась в том, что в URL2 нет запроса в соответствии со стандартом.

Кроме того, еще одна вещь ... при выполнении 'Траливали' == $_GET['query'] это будетТолько в том случае, если ваш PHP-скрипт сам кодируется в UTF-8.Ваш текстовый редактор должен быть в состоянии сообщить вам кодировку вашего файла.

2 голосов
/ 30 июля 2010

Как кодируется фрагмент, к сожалению, зависит от браузера :

Кодируется ли идентификатор фрагмента (хэш) с использованием правил обхода URL-адресов, предписанных RFC?
MSIE: НЕТ
Firefox: ЧАСТИЧНО
Сафари: ДА
Опера: НЕТ
Хром: НЕТ
Android: ДА

Что касается вопроса о том, какую кодировку использует браузер для кодирования международных (читай: не ASCII) символов перед их преобразованием в %nn escape-последовательности, «большинство браузеров решают эту проблему, отправляя данные UTF-8 по умолчанию на любой текст, введенный вручную в строку URL и использующий кодировку страницы для всех следующих ссылок. " (тот же источник ).

2 голосов
/ 30 июля 2010
rawurldecode($_GET['query']);

но на самом деле это должно было быть сделано php; -)

edit Вы заявляете, что "ничего не работает" - что вы пытаетесь? если текст не отображается на экране так, как вы хотите, например, когда вы echo $_GET['query'];, вашей проблемой может быть кодировка, указанная вами для страницы, отправленной обратно в браузер.

Включить строку

header("Content-Type: text/html; charset=utf-8");

и посмотрите, поможет ли это.

1 голос
/ 03 июня 2011

Вы можете использовать UTF8::autoconvert_request() для этого.

Для получения дополнительной информации посмотрите http://code.google.com/p/php5-utf8/.

0 голосов
/ 30 июля 2010

RFC 1738 гласит, что в URL не кодируются только буквенно-цифровые символы, специальные символы $-_.+!*'()," и зарезервированные символы ;/?:@=&. Все остальное кодируется HTTP-клиентом, то есть веб-браузером. Вы можете использовать rawurldecode () независимо от того, PHP автоматически декодирует строку запроса. В двойном декодировании опасности нет.

0 голосов
/ 30 июля 2010

Ответ прост: кодируемая строка всегда . Как указано в стандарте HTTP.
А что такое Firefox отображает - не имеет значения.

Кроме того, поскольку PHP автоматически декодирует строку запроса, декодирование также не требуется.

Обратите внимание, что '% D2% F0% E0% EB% E8% E2% E0% EB% E8' является однобайтовой кодировкой, поэтому ваша страница, вероятно, написана в 1251. По крайней мере, заголовок HTTP сообщает об этом браузеру .
В то время как AJAX всегда использует utf-8.

Итак, вам просто нужно использовать одну кодировку (utf-8) для своих страниц или отличать вызовы ajax от обычных.

Что касается фрагмента - не используйте значение фрагмента для отправки его на сервер. Иметь переменную JS, а затем использовать ее дважды - для установки фрагмента и отправки на сервер с использованием JSON.

0 голосов
/ 30 июля 2010

URL-адреса ограничены определенными символами ascii. Предполагается, что символы, не относящиеся к URL, должны быть закодированы по URL (кодирование% hh, которое вы видите). Некоторые браузеры могут автоматически кодировать URL-адреса, отображаемые в строке адреса.

...