webew
Войти » Регистрация
 
PHP
JavaScript
Протоколы

Русские буквы в URL страниц

6 февраля 2010, 2:59
Автор: 1234ru
Товарищи, никак не могу понять, что из себя представляют адреса, содержащие русские буквы.
Да, читал про кодирование нелатинских символов в URL.

Вместе с тем, складывается впечатление, что каждый браузер обращается с адресами страниц по-разному: один кодирует, второй не кодирует, третий недокодирует.
Вот такой несложный javascript-код

<script type="text/javascript">
document.write(document.URL);
</script>

для страницы с адресом (точнее, с куском адреса) вида ф?q=ф дал в трёх браузерах три разных результата:
IE6: ф?q=ф
FF3.0: %D1%84?q=%F4
Chrome4: %D1%84?q=%D1%84
Особенно порадовал фаерфокс. Который символы в части path закодировал как UTF-8, а в части query - как CP-1251 (вообще полный привет, по-моему).

upd: проверил: от кодировки страницы результат не зависит ни в одном браузере.


Я весьма озадачен, т.к. мне нужно при помощи javascript'ового счетчика (навроде liveinternet'а) собирать урлы и рефереры с разных страниц (неизвестно каких сайтов) и разных браузеров, поэтому необходимо всё это мракобесие как-то привести к единому виду.

Пролейте кто-нибудь луч света, пожалуйста.
Добавить комментарий
Отображение комментариев: Древовидное | Плоское

bur

Обычно кириллицу в URL кодируют с полмощью методов encodeURI и encodeURIComponent.
08.02.2010, 12:02
Ответить

1234ru

Кодирование - это следующий шаг.

Проблема же возникает еще до кодирования, т.к. то, что будет кодироваться, в разных браузерах оказывается разное.
Из IE 6 придет закодированное ф?q=ф, из FF - закодированное %D1%84?q=%F4. И фиг поймешь, что это одна и та же страница пришла...
То, что не убивает нас, делает нас инвалидами.
08.02.2010, 21:18
Ответить

paulus

Firefox поступил ровно так, как ожидается: url кодируется в utf8 (такая договоренность),
данные формы приезжают в кодировке страницы (так будут ожидать скрипты). ИЕ6 писался
американцами, которые не знают ничего, кроме latin1 (ср. с IE7, который писали индийцы).
Хром расстроил :( Видимо, он писался американцами, которые верят, что замена latin1 на
utf8 ведет к решению всех проблем с кодировками.

Rule of thumb: не использовать русские буквы в url и параметры ожидать в кодировке страницы.
08.02.2010, 13:21
Ответить

1234ru

Специально для фаерфокса:

<?php header("Content-type: text/html; charset=UTF-8"); ?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang='ru-RU'>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body>
    <script type="text/javascript">
    document.write(document.URL);
    </script>
</body>
</html>


Результат тот же. Причем не меняется, если кодировку поменять на latin-1...

Так что данные формы приезжают, скорее, в кодировке винды, чем в кодировке страницы (это единственное у меня предположение, почему он так упорно кодирует GET-запрос в CP-1251), а URL кодируется как UTF-8.

Цитата:
Rule of thumb: не использовать русские буквы в url и параметры ожидать в кодировке страницы.

К сожалению, мне нужно собирать данные не со своих страниц... Которые неизвестно в каком браузере просматриваются и вообще неизвестно кем делались..

Я уже щас думаю - не составить ли список user-agent'ов по самым распространенным браузерам и не разобрать ли каждый случай руками...
Интересно, как liveinternet с этим справился.

В общем, надо думать. Чувствую, кроме какой-нибудь дикости ничего не придумается..
То, что не убивает нас, делает нас инвалидами.
08.02.2010, 21:27
Ответить

1234ru

Тут оказалось, что в Firefox (по крайней мере, в виндовом) есть настройка
network.standard-url.encode-query-utf8, которая по умолчанию установлена в false (идиотская опция, по-моему, вообще)
Поэтому он и прёт содержимое запроса в CP-1251, если его в адресную строку вписывать руками.
Если GET -запрос пришёл из перехода по ссылке - кодирует так же, как и сам адрес - в UTF-8.

Хром всегда кодирует и адрес, и запрос в UTF-8.
Internet Explorer (шестой) не кодирует вообще. (а что там с седьмым? он как кодирует? тоже в utf?)

Ладно, так хоть полегче.
Можно тогда все адреса прогонять через urldecode(). Те, что закодированы - раскодируются, тем, что не закодированы, по идее, ничего не будет.. Собственно, как я сейчас и делаю.
Хотя это не очень круто, конечно, так грубо подходить к вопросу, но тут лучше не придумаешь, по-моему...
То, что не убивает нас, делает нас инвалидами.
09.02.2010, 02:54
Ответить

1234ru

Цитата:
ИЕ6 писался американцами, которые не знают ничего, кроме latin1


Тогда я что-то не понял такой результат.
Делается страница с адресом /ф?q=ф и на ней - ссылка на неё же, и смотрится, что показывает реферер ($_SERVER[HTTP_REFERER]).

Кодировка 1251. Всё нормально. реферер показывает исходное /ф?q=ф

Кодировка UTF-8. Реферер не виден (видно два знака вопроса - ?? т.е. какая-то фигня.)
Кодировка в настройках стоит UTF-8. При смене её на 1251 показывает /ф?q=ф
При переходе по этой ссылке показывает

В KOI8-R приезжает /Т?q=Т. ф в cp1251- это байт со значением 244, которому в KOI8-R соответствует как раз буква Т.
Опять же при смене кодировки просмотра (в браузере) на 1251 показывается /ф?q=ф


Откуда такая любовь к 1251? (винда английская, только региональные установки времени и даты российские)


Не знаю, короче, как учитывать IE6...
То, что не убивает нас, делает нас инвалидами.
10.02.2010, 09:16
Ответить

1234ru

Короче, по результатам исследований картина такая:

Протестированы Chrome 4, FF 3.5, Opera 10.10 и IE6.0 (7 и выше не пробовал).

IE 6 хранит адрес страницы (т.е. document.URL) в её кодировке (т.е. оставляет его без изменений).
Реферер отправляет в windows-1251 :0
urlencode не делается ни в каком случае.

Все остальные протестированные браузеры переводят часть path (т.е. до знака вопроса) REFERER'а в UTF-8, после чего весь его кодируют с помощью urlencode.

Chrome и Firefox точно так же хранят и сам адрес страницы.

Opera часть path оставляет без изменений в исходной кодировке страницы (и без urlencode), часть query кодирует urlencode.
То, что не убивает нас, делает нас инвалидами.
14.02.2010, 02:02
Ответить

bur

Если не вдаваться в дебри кодирования кириллицы браузерами, а решать поставленную задачу (собирать урлы и рефереры js-счетчиками), то можно взять решение лиру. Вот код их счетчика:
<!--LiveInternet counter--><script type="text/javascript"><!--
document.write("<a class='nob' href='http://www.liveinternet.ru/click' "+
"target=_blank>

<img src='http://counter.yadro.ru/hit?t45.1;r"+
escape(document.referrer)+((typeof(screen)=="undefined")?"":
";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth?
screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+
";h"+escape(document.title.substring(0,80))+";"+Math.random()+
"'
alt='' title='LiveInternet' "+
"
border=0 width=31 height=31>
<\/a>")//--></script><!--/LiveInternet-->

Если приглядеться, заметим, что для кодирования урлов они используют метод escape, который переводит строку в шестнадцатеричный Unicode. На сервере необходимо для полученных полей выполнить unescape. Такой функции в PHP нет, но можно найти реализации. После php_unescape (обозвал для примера) выполни на сервере urldecode, на случай, если URL был в стандартной кодировке URI.

Оно? Или я не так понял задачу.
09.02.2010, 12:25
Ответить

1234ru

Да, оно самое (я, в общем-то, его и использовал, просто кое-где перепутал, поэтому у меня были ошибки).

Мне тут пришло несколько мыслей, из которых изложу пока две:

1. Почему бы адрес страницы, где стоит счетчик, не получать прямо на сервере счетчика через $_SERVER['HTTP_REFERER'] ?
Ведь эта страница по отношению к счетчику является rereferом (с неё приходит запрос на счетчик).
Через $_SERVER['HTTP_REFERER'] было бы удобнее: не надо дописывать лишний GET-параметр.

2. Math.random() призвана не допустить кэширования. Нельзя ли этого добиться, отдавая с сервера счетчика изображение с заголовком "Cache-control: no-cache" ?
То, что не убивает нас, делает нас инвалидами.
10.02.2010, 08:04
Ответить
NO USERPIC

rgbeast

Referer не всегда передается - security, файрволы и некоторые клиенты его режут. no-cache не на все клиенты действует. Бывают, например, случаи, что в локальной сети стоит кэширующий прокси (ради экономии трафика), который на no-cahe забивает.
10.02.2010, 08:36
Ответить

1234ru

Т.е., например, вариант счетчика, реализованный через <noscript> для отключенного Javascriptа, в таких случаях будет неизбежно закэширован?
То, что не убивает нас, делает нас инвалидами.
10.02.2010, 08:56
Ответить
NO USERPIC

rgbeast

Будет, но это уже второй порядок малости (произведение двух небольших вероятностей), можно пренебречь.
10.02.2010, 10:35
Ответить

bur

Math.random() - 100% гарантия, что счетчик будет взят не из кэша. Рандомный гет-параметр повсеместно используется для счетчиков и ajax-запросов.
10.02.2010, 11:34
Ответить

1234ru

Цитата:
На сервере необходимо для полученных полей выполнить unescape. Такой функции в PHP нет, но можно найти реализации. После php_unescape (обозвал для примера) выполни на сервере urldecode, на случай, если URL был в стандартной кодировке URI.


На самом деле всё даже сложнее.
Поскольку во многих браузерах document.URL уже закодирован с помощью urlencode (подробнее о том, как себя ведут те или иные браузеры - см. выше в этой же теме). После действия escape знаки процента будут повторно закодированы.
Упомянутые реализации unescape раскодируют только последовательности вида %uHHHH, т.е. закодированные знаки процента они не тронут и закодированный, например, из фаерфокса адрес останется без изменений.

Т.е.:
исходный адрес (KOI8-R):   http://ф?q=ф
document.URL(firefox):  http://%D1%84?q=%C6
escape(document.URL):   http%3A//%25D1%2584%3Fq%3D%25C6   ( : => %3A, % => %25 )

=== приняли GET-параметры на сервере, получаем: ===

после unescape: http%3A//%25D1%2584%3Fq%3D%25C6 (то же самое)
после urldecode: http://%D1%84?q=%C6
еще раз urldecode: http://ф?q=абра-кадабра (потому что query был неизвестно в какой кодировке)
То, что не убивает нас, делает нас инвалидами.
14.02.2010, 02:49
Ответить
NO USERPIC

keugene

Кто подскажет
Добавил на сайт русские URLы

в Опере и Мозиле при наведении на такую ссылку title ссылки отображается нормально
а в IE выглядит в перекодированном виде, есть ли возможность исправить?
22.06.2010, 18:21
Ответить

1234ru

Навряд ли.. Разное отображение title - это особенность браузера. Заставить, например, Internet Explorer 6 не кодировать нелатинские символы никак нельзя.
То, что не убивает нас, делает нас инвалидами.
22.06.2010, 19:54
Ответить
Добавить комментарий
Отображение комментариев: Древовидное | Плоское
© 2008—2024 webew.ru, связаться: x собака webew.ru
Сайт использует Flede и соответствует стандартам WAI-WCAG 1.0 на уровне A.
Rambler's Top100

Реклама: