Как правильно URL кодировать символы Юникода? - PullRequest
105 голосов
/ 27 мая 2009

Я знаю о нестандартной схеме% uxxxx, но это не кажется мудрым выбором, поскольку W3C отклонила эту схему.

Несколько интересных примеров:

Характер сердца. Если я наберу это в моем браузере:

http://www.google.com/search?q=♥

Затем скопируйте и вставьте его, я вижу этот URL

http://www.google.com/search?q=%E2%99%A5

, из-за чего кажется, что Firefox (или Safari) делает это.

urllib.quote_plus(x.encode("latin-1"))
'%E2%99%A5'

, что имеет смысл, за исключением вещей, которые не могут быть закодированы в Latin-1, например, символ тройной точки.

Если я наберу URL

http://www.google.com/search?q=…

в мой браузер, затем скопируйте и вставьте, я получаю

http://www.google.com/search?q=%E2%80%A6

назад. Который, кажется, результат выполнения

urllib.quote_plus(x.encode("utf-8"))

, что имеет смысл, поскольку ... не может быть закодировано с помощью Latin-1.

Но тогда мне не ясно, как браузер знает, декодировать ли с помощью UTF-8 или Latin-1.

Так как это кажется неоднозначным:

In [67]: u"…".encode('utf-8').decode('latin-1')
Out[67]: u'\xc3\xa2\xc2\x80\xc2\xa6'

работает, поэтому я не знаю, как браузер определяет, декодировать ли это с помощью UTF-8 или Latin-1.

Что правильно делать со специальными символами, с которыми мне нужно иметь дело?

Ответы [ 5 ]

61 голосов
/ 27 мая 2009

Я бы всегда кодировал в UTF-8. Со страницы Википедии о процентном кодировании :

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

Похоже, что в прошлом существовали и другие приемлемые способы кодирования URL, браузеры пытаются использовать несколько методов декодирования URI, но если вы используете кодировку, вам следует использовать UTF-8.

9 голосов
/ 28 мая 2009

Похоже, что общее правило заключается в том, что браузеры кодируют ответы формы в соответствии с типом содержимого страницы, с которой была получена форма. Это предположение, что если сервер отправляет нам «text / xml; charset = iso-8859-1», то они ожидают ответы обратно в том же формате.

Если вы просто вводите URL-адрес в строке URL-адреса, то в браузере нет базовой страницы для работы, и поэтому ему просто нужно угадать. Так что в этом случае кажется, что он выполняет utf-8 все время (так как оба ваших ввода выдают трехоктетные значения формы).

Печальная правда в том, что в AFAIK не существует стандарта для того, какой набор символов должен содержать значения в строке запроса или любые символы в URL-адресе. По крайней мере, в случае значений в строке запроса нет оснований полагать, что они обязательно do соответствуют символам.

Это известная проблема, когда вы должны сообщить своей серверной платформе, какой набор символов вы ожидаете, чтобы строка запроса была закодирована как --- например, в Tomcat вы должны вызвать request.setEncoding () (или какой-либо подобный метод ) до вы вызываете любой из методов request.getParameter (). Недостаток документации по этому вопросу, вероятно, отражает недостаточную осведомленность о проблеме среди многих разработчиков. (Я регулярно спрашиваю интервьюируемых на Java, в чем разница между Reader и InputStream, и регулярно получаю пустые взгляды)

7 голосов
/ 20 июня 2009

IRI ( RFC 3987 ) является новейшим стандартом, который заменяет стандарты URI / URL ( RFC 3986 и более старые). URI / URL изначально не поддерживают Unicode (ну, RFC 3986 добавляет положения для будущих протоколов на основе URI / URL для его поддержки, но не обновляет предыдущие RFC). Схема «% uXXXX» является нестандартным расширением, позволяющим использовать Unicode в некоторых ситуациях, но не всегда реализуется всеми. IRI, с другой стороны, полностью поддерживает Unicode и требует, чтобы текст кодировался как UTF-8, а затем кодировался в процентах.

6 голосов
/ 14 апреля 2010

IRI не заменяют URI, потому что в некоторых контекстах допустимы только URI (фактически, ASCII), включая HTTP.

Вместо этого вы указываете IRI, и он превращается в URI при выходе из сети.

0 голосов
/ 27 мая 2009

Первый вопрос: каковы ваши потребности? Кодировка UTF-8 является довольно хорошим компромиссом между получением текста, созданного с помощью дешевого редактора, и поддержкой широкого спектра языков. Что касается браузера, идентифицирующего кодировку, ответ (от веб-сервера) должен сообщить браузеру кодировку. Тем не менее, большинство браузеров пытаются угадать, потому что во многих случаях это либо отсутствует, либо ошибается. Они предполагают, прочитав некоторое количество потока результатов, чтобы увидеть, есть ли символ, который не помещается в кодировку по умолчанию. В настоящее время все браузеры (? Я не проверял это, но это довольно близко к истине) используют utf-8 по умолчанию.

Так что используйте utf-8, если у вас нет веских причин использовать одну из многих других схем кодирования.

...