Введение

Веб-страницы, созданные с использованием языка гипертекстовой разметки (HTML), могут содержать многоязычный текст, представленный универсальным набором символов Unicode. Ключевым моментом в отношениях между Unicode и HTML является взаимосвязь между "набором символов документа", который определяет, какие символы могут присутствовать в HTML-документе и присваивает им числовые значения, и "внешней кодировкой символов", или "charset", используемой для кодирования данного документа в виде последовательности байтов. В RFC 1866, первоначальном стандарте HTML 2.0, набор символов документа был определен как ISO 8859-1 (в более поздних стандартах HTML по умолчанию используется кодировка Windows-1252). Он был расширен до ISO 10646 (который по сути эквивалентен Unicode). Этот набор не меняется в зависимости от языка документов или платформы, на которой они созданы. Внешняя кодировка символов выбирается автором документа (или программным обеспечением, которое он использует для создания документа) и определяет, как байты, используемые для хранения и/или передачи документа, соотносятся с символами из набора символов документа. Символы, отсутствующие в выбранной внешней кодировке, могут быть представлены с помощью ссылок на символьные сущности. Взаимосвязь между Unicode и HTML часто представляет собой сложную тему для многих IT-специалистов, авторов документов и пользователей сети. Точное отображение текста на веб-страницах, использующих разные языки и системы письма, усложняется деталями кодировки символов, синтаксисом языка разметки, шрифтами и различной степенью поддержки веб-браузерами.

Знаки документа HTML

Веб-страницы обычно представляют собой HTML или XHTML документы. Оба типа документов состоят, на фундаментальном уровне, из символов, которые являются графемами и графемоподобными единицами, независимо от того, как они представлены в компьютерных системах хранения и сетях. HTML-документ представляет собой последовательность символов Unicode. Более конкретно, документы HTML 4.0 должны состоять из символов, входящих в набор символов HTML-документа: репертуар символов, в котором каждому символу присвоен уникальный, неотрицательный целочисленный код. Этот набор определяется в DTD HTML 4.0, который также устанавливает синтаксис (допустимые последовательности символов), позволяющий создать корректный HTML-документ. Набор символов HTML-документа для HTML 4.0 состоит из большинства, но не всех символов, совместно определенных Unicode и ISO/IEC 10646: Универсальным набором символов (UCS). Как и HTML-документы, XHTML-документ представляет собой последовательность символов Unicode. Однако XHTML-документ является XML-документом, который, хотя и не имеет явного уровня абстракции "символа документа", тем не менее опирается на аналогичное определение допустимых символов, охватывающее большинство, но не все определения символов Unicode/UCS. Наборы, используемые HTML и XHTML/XML, немного различаются, но эти различия мало влияют на обычного автора документа. Независимо от того, является ли документ HTML или XHTML, при хранении в файловой системе или передаче по сети символы документа кодируются как последовательность бит-октетов (байтов) в соответствии с определенной кодировкой символов. Эта кодировка может быть форматом преобразования Unicode, например UTF-8, который может напрямую кодировать любой символ Unicode, или устаревшей кодировкой, например Windows-1252, которая не может этого делать. Однако даже при использовании кодировок, не поддерживающих все символы Unicode, закодированный документ может использовать числовые ссылки на символы. Например, ☺ (☺) используется для обозначения символа улыбающегося лица в наборе символов Unicode.

Кодирование символов

Для поддержки всех символов Unicode без использования числовых ссылок на символы, веб-страница должна использовать кодировку, охватывающую весь Unicode. Наиболее популярной является UTF-8, в которой символы ASCII, такие как английские буквы, цифры и некоторые другие часто используемые символы, сохраняются без изменений по отношению к ASCII. Это позволяет сохранить HTML-код (например, <br> и </div>) неизменным по сравнению с ASCII. Символы, находящиеся за пределами диапазона ASCII, хранятся в 2–4 байтах. Также можно использовать UTF-16, где большинство символов хранятся в виде двух байтов с различным порядком байтов (endianness), что поддерживается современными браузерами, но используется реже.

Цифровые символы

Чтобы обойти ограничения устаревших кодировок, HTML разработан таким образом, что можно представить символы из всего набора Unicode внутри HTML-документа, используя числовую ссылку на символ – последовательность символов, явно указывающую кодовую точку Unicode представляемого символа. Числовая ссылка на символ имеет вид &#N;, где N – это либо десятичное число, соответствующее кодовой точке Unicode, либо шестнадцатеричное число, которое в этом случае должно начинаться с «x». Символы, составляющие числовую ссылку, универсально представимы во всех кодировках, утвержденных для использования в Интернете. Поддержка шестнадцатеричных чисел в этом контексте появилась относительно недавно, поэтому старые браузеры могут испытывать проблемы с отображением символов, на которые ссылаются шестнадцатеричными числами, но, вероятно, у них все равно возникнут проблемы с отображением символов Unicode с кодовой точкой выше 255. Для обеспечения лучшей совместимости со старыми браузерами до сих пор распространена практика преобразования шестнадцатеричной кодовой точки в десятичное значение (например, &#21512; вместо &#x5408;).

Именные сущности символов

В HTML 4 существует стандартный набор из 252 именованных символьных сущностей для символов, некоторые из которых распространены, а некоторые – малоизвестны, которые либо отсутствуют в определенных кодировках символов, либо имеют особое значение в некоторых контекстах (например, угловые скобки и кавычки). Хотя любой символ Unicode можно указать по его числовому коду, некоторые авторы HTML-документов предпочитают использовать эти именованные сущности, когда это возможно, поскольку они менее сложны для запоминания и лучше поддерживались старыми браузерами. Символьные сущности включаются в HTML-документ с помощью ссылок на сущности, имеющих вид &EntityName;, где EntityName – имя сущности. Например, &mdash;, как и &#8212; или &#x2014;, представляет собой: символ длинного тире "—", даже если используемая кодировка символов не содержит этот символ. Полный список можно найти здесь: Список ссылок на символьные сущности XML и HTML.

Определение кодирования символов

Для корректной обработки HTML веб-браузер должен установить, какие символы Юникода соответствуют закодированной форме HTML-документа. Для этого веб-браузер должен знать, какая кодировка использовалась.

Кодирование информации

Когда документ передается через сообщение MIME или транспорт, использующий типы содержимого MIME, такие как ответ HTTP, сообщение может указывать кодировку с помощью заголовка Content Type, например Content Type: text/html; charset=UTF-8. Другие внешние способы объявления кодировки допустимы, но используются редко. Если документ использует кодировку Unicode, информация о кодировке также может присутствовать в виде метки порядка байтов (BOM). Наконец, кодировку можно объявить с помощью синтаксиса HTML. Для сериализации text/html, если страница закодирована в расширении ASCII (например, UTF-8, а не UTF-16), можно использовать мета-элемент, такой как <meta http-equiv="content-type" content="text/html; charset=UTF-8"> или (начиная с HTML5) <meta charset="UTF-8">. Для HTML-страниц, сериализованных как XML, варианты объявления заключаются либо в использовании кодировки по умолчанию (которая для XML-документов – UTF-8), либо в использовании объявления кодировки XML. Мета-атрибут не играет никакой роли в HTML, передаваемом как XML.

Кодирование по умолчанию

Кодировка по умолчанию применяется, когда отсутствует внешнее или внутреннее объявление кодировки, а также отсутствует метка порядка байтов. В то время как кодировка по умолчанию для HTML-страниц, передаваемых как XML, обязана быть UTF-8, кодировка по умолчанию для обычной веб-страницы (то есть для HTML-страниц, сериализованных как text/html) зависит от языковых настроек браузера. Для системы, настроенной преимущественно для западноевропейских языков, обычно используется Windows-1252. Для локалей, использующих кириллицу, по умолчанию применяется Windows-1251. Для браузера, используемого в регионе, где распространены устаревшие многобайтовые кодировки символов, скорее всего, будет применено какое-либо автоматическое определение кодировки.

Тенденции кодирования

Из-за исторически сложившейся практики 8-битных текстовых представлений в языках программирования и операционных системах, а также стремления избавить пользователей от необходимости разбираться в тонкостях кодирования, многие текстовые редакторы, используемые разработчиками HTML, не предоставляют или не желают предоставлять выбор кодировки при сохранении файлов на диск и зачастую даже не позволяют вводить символы за пределами очень ограниченного набора. В результате многие разработчики HTML не осведомлены о проблемах кодирования и могут даже не знать, какая кодировка используется в их документах. Недопонимание, например, уверенность в том, что объявление кодировки изменяет фактическую кодировку (в то время как это лишь метка, которая может быть неверной), также является причиной такого подхода редакторов. Дополнительным фактором, влияющим в том же направлении, является распространение UTF-8, которое значительно снижает потребность в других кодировках, поэтому современные редакторы, как правило, по умолчанию, в соответствии с рекомендациями спецификации HTML5, используют UTF-8.

Знак байтовой последовательности/уникодный нюх

Для обеих сериализаций HTML (тип содержимого "text/html" и тип содержимого "application/xhtml+xml") знак порядка байтов (BOM) является эффективным способом передачи информации о кодировке внутри HTML-документа. Для UTF-8 BOM является необязательным, а для кодировок UTF-16 и UTF-32 – обязательным. (Примечание: UTF-16 и UTF-32 без BOM формально известны под другими названиями, представляют собой различные кодировки и, следовательно, требуют какой-либо формы объявления кодировки – см. UTF-16BE, UTF-16LE, UTF-32LE и UTF-32BE.) Использование символа BOM (U+FEFF) означает, что кодировка автоматически определяется любым приложением, осуществляющим обработку. Приложениям обработки достаточно искать в потоке байтов начальный 0x0000FEFF, 0xFEFF или 0xEFBBBF, чтобы идентифицировать документ как закодированный в UTF-32, UTF-16 или UTF-8 соответственно. Для этих кодировок не требуются дополнительные механизмы метаданных, поскольку знак порядка байтов содержит всю информацию, необходимую для обработки. В большинстве случаев символ порядка байтов обрабатывается приложениями редактирования отдельно от других символов, поэтому существует небольшой риск удаления или изменения знака порядка байтов автором, что привело бы к указанию неверной кодировки (как это может произойти при объявлении кодировки на английском/латинском языке). Если в документе отсутствует знак порядка байтов, тот факт, что первый непробельный печатный символ в HTML-документе должен быть "<" (U+003C), может быть использован для определения кодировки UTF-8, UTF-16 или UTF-32.

Кодирование переопределяется

Многие HTML-документы передаются с неточной информацией о кодировке или вообще без информации о кодировке. Чтобы определить кодировку в таких случаях, многие браузеры позволяют пользователю вручную выбрать имя кодировки из списка. Они также могут использовать алгоритм автоматического определения кодировки, который работает совместно с BOM, а в случае HTML, представленного как XML – в обход ручной настройки. Для HTML-документов, сериализованных как text/html, ручная настройка может применяться ко всем документам или только к тем, чью кодировку невозможно установить, анализируя объявления и/или байтовые шаблоны. Тот факт, что ручная настройка присутствует и широко используется, препятствует внедрению точных объявлений кодировки в Интернете, поэтому проблема, вероятно, сохранится. Однако стоит отметить, что Internet Explorer, Chrome и Safari для сериализаций XML и text/html не разрешают изменять кодировку, если страница содержит BOM. Для HTML-документов, сериализованных с предпочтительной XML-меткой application/xhtml+xml, ручное изменение кодировки запрещено. Попытка изменить кодировку такого XML-документа приведет к тому, что он перестанет быть XML, поскольку наличие объявления кодировки с обнаруживаемыми ошибками является фатальной ошибкой для XML-документов. В настоящее время браузеры Gecko, такие как Firefox, следуют этому правилу, в то время как большинство других распространенных браузеров, поддерживающих HTML как XML, например, браузеры Webkit (Chrome/Safari), позволяют вручную изменять кодировку документов XHTML.

Поддержка веб-браузера

Многие браузеры способны отображать лишь небольшую часть полного репертуара Unicode. Вот как ваш браузер отображает различные кодовые точки Unicode:

+Пример поддержки Unicode в веб-браузере СимволHTML char refUnicode nameЧто отображает ваш браузер U+0041 &#65; или &#x41; Latin capital letter A A U+00DF &#223; или &#xDF; Latin small letter Sharp S ß U+00FE &#254; или &#xFE; Latin small letter Thorn þ U+0394 &#916; или &#x394; Greek capital letter Delta Δ U+017D &#381; или &#x17D; Latin capital letter Z with háček Ž U+0419 &#1049; или &#x419; Cyrillic capital letter Short I Й U+05E7 &#1511; или &#x5E7; Hebrew letter Qof ק U+0645 &#1605; или &#x645; Arabic letter Meem م U+0E57 &#3671; или &#xE57; Thai digit 7 ๗ U+1250 &#4688; или &#x1250; Ge'ez syllable Qha ቐ U+3042 &#12354; или &#x3042; Hiragana letter A (Japanese) あ U+53F6 &#21494; или &#x53F6; CJK Unified Ideograph 53F6 (Simplified Chinese "Leaf") 叶 U+8449 &#33865; или &#x8449; CJK Unified Ideograph 8449 (Traditional Chinese "Leaf") 葉 U+B5AB &#46507; или &#xB5AB; Hangul syllable Tteolp (Korean "Ssangtikeut Eo Rieulbieup") 떫 U+16A0 &#5792; или &#x16A0; Runic letter Fehu ᚠ U+0D37 &#3383; или &#x0D37; Malayalam letter ഷ (ṣha) ഷ U+1F602 &#128514; или &#x1F602; Face with Tears of Joy emoji 😂 Для отображения всех вышеперечисленных символов вам может потребоваться установить один или несколько крупных многоязычных шрифтов, например Code2000. Некоторые веб-браузеры, такие как Mozilla Firefox, Opera, Safari и Internet Explorer (начиная с версии 7), способны отображать многоязычные веб-страницы, интеллектуально выбирая шрифт для отображения каждого отдельного символа на странице. Они будут правильно отображать любую комбинацию блоков Unicode, если в операционной системе установлены соответствующие шрифты. Более старые браузеры, такие как Netscape Navigator 4.77 и Internet Explorer 6, могут отображать только текст, поддерживаемый текущим шрифтом, связанным с кодировкой символов страницы, и могут неправильно интерпретировать числовые ссылки на символы как ссылки на кодовые значения в текущей кодировке символов, а не как ссылки на кодовые точки Unicode. При использовании такого браузера маловероятно, что ваш компьютер будет содержать все эти шрифты, или что браузер сможет использовать все доступные шрифты на одной странице. В результате браузер не будет правильно отображать текст в приведенных выше примерах, хотя он может отобразить их часть. Однако, поскольку они закодированы в соответствии со стандартом, они будут отображаться правильно на любой системе, соответствующей требованиям и имеющей необходимые символы. Кроме того, символы, которым присвоены имена для использования в именованных ссылках на сущности, скорее всего, будут более распространены, чем другие. Для отображения символов за пределами базовой многоязычной плоскости, таких как готическая буква faihu, которая является вариантом рунической буквы fehu в таблице выше, некоторым системам (например, Windows 2000) потребуется ручная настройка параметров.

Частота использования

Согласно внутренним данным веб-индекса Google, в декабре 2007 года кодировка UTF-8 Unicode стала наиболее часто используемой кодировкой на веб-страницах, обогнав ASCII (США) и 8859-1/1252 (Западная Европа).