Хотя действительно можно вручную выбрать некоторую кодировку (и не забывать отключить ее при посещении другого сайта), на самом деле веб-сайт должен был правильно ее указать. Либо сервер, либо сами веб-страницы должны что-то указывать, иначе все, что может сделать браузер, - это сделать какое-то лучшее предположение. И, конечно, если кодировка будет указана, то HTML документ должен фактически использовать эту кодировку. Не так много для веб-сайта из вопроса, как показано ниже:
Чтобы увидеть, указал ли веб-сервер что-то, нужно взглянуть на так называемые заголовки . Используя онлайн-сервис от web-sniffer.net, вы сможете найти заголовки, которые вы получите:
HTTP / 1.1 200 ОК Дата: пн, 17 августа 2009 17:47:03 GMT Сервер: Apache Дата последнего изменения: понедельник, 27 ноября 2006 г. 23:38:49 GMT ETag: "758b0606-1a316-4234309151440" Accept-Ranges: байты Длина содержимого: 107286 Подключение: закрыть Content-Type: text / html; charset = utf-8 (спецификация UTF-16, буквенный номер)
Последняя строка кажется немного странной: как сервер может претендовать на то, чтобы быть как UTF-8, так и UTF-16? Значение для charset
должно быть одним из тех, которые зарегистрированы в IANA (например, UTF-8 без каких-либо комментариев). Однако использование анализатора пакетов Wireshark вместо онлайн-сервиса показывает, что текст (BOM UTF-16, litte-endian) фактически является комментарием от онлайн-сервиса, а не отправляется веб-сервером.
Итак: веб-сервер утверждает, что отправит нам HTML-документ в кодировке UTF-8.
Однако следующий HTML-документ неверен (отредактирован для удобства чтения):
! <! DOCTYPE html PUBLIC "- // W3C // DTD HTML 4.01 Transitional // EN"> <HTML> <Голова> <title> Урок 5 </ title> <meta http-equ = "Content-Type" content = "text / html; charset = utf-8"> <link href = "main.css" rel = "stylesheet" type = "text / css"> </ HEAD> ...
Выше строка, указывающая тип контента, должна появляться первой внутри <head>
, потому что иначе браузер не будет знать, как обрабатывать специальные символы в <title>
. Еще важнее то, что первые два нечетных символа ÿþ
на самом деле представляют собой шестнадцатеричные коды FF и FE, которые, как уже отмечалось в онлайн-сервисе, являются меткой порядка байтов для UTF-16, litte-endian.
Итак: веб-сервер пообещал отправить UTF-8, но затем отправил маркеры, которые указывали UTF-16 LE. Далее в HTML-документе утверждается, что он снова использует UTF-8.
Действительно, Wireshark показывает, что настоящий документ HTML имеет кодировку UTF-16. Это означает, что каждый символ отправляется с использованием не менее двух байтов (октетов). Как 6 символов в <html>
посылаются как 12 шестнадцатеричных байтов 3C 00 68 00 74 00 6D 00 6C 00 3E 00
. Тем не менее, этот самый веб-сайт вполне мог быть простым ASCII, так как на нем, похоже, вообще не используются символы не-ASCII. Вместо этого источник HTML полон числовых ссылок на символы ( NCR ), таких как:
यह दिल्ली शहर है।
Браузер отображает вышеизложенное как यह दिल्ली शहर है।. Однако из-за использования NCR и UTF-16 для одного символа य ( Unicode U + 092F ) требуется до 14 байтов 26 00 23 00 32 00 33 00 35 00 31 00 3B 00
, поскольку он записывается с использованием NCR, य
а 7 символов ASCII самого NCR кодируются с использованием UTF-16., Когда не используются NCR, в UTF-8 для этого одиночного require потребуется 3 байта ( E0 A4 AF
), а в UTF-16 - два байта ( 09 2F
).
Для этого источника HTML использование UTF-16 является полной тратой пропускной способности, и сервер также не использует сжатие.