Кодировка символов в HTML, CSS и JavaScript

Введение в кодирование символов / текста в Интернете

В этой статье мы узнаем о различных методах отображения символов в кодировке ASCII и UTF в JavaScript, CSS и HTML.

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

Я подробно рассмотрел кодировку символов в этой статье. Я рекомендую вам сначала прочитать тему Кодировка символов в этой статье, прежде чем читать что-либо дальше. Но если вы понимаете, как работает кодировка символов ASCII и UTF, вы можете пропустить ее.

Когда браузер получает файл или данные с сервера, запрос обычно содержит с ним заголовок Content-Type. Этот заголовок определяет MIME-тип документа и его кодировку.

Например, HTML-файл, отправленный сервером, будет иметь заголовок Content-Type со значением text/html;charset=UTF-8. Это значение используется браузером для надлежащей визуализации HTML-документа, если полученный документ имеет формат HTML и закодирован в кодировке UTF-8.

Однако мы также можем указать кодировку HTML-документа в самом документе, используя метатег http-equiv="content-type".

<meta http-equiv="content-type" content="text/html; charset=UTF-8">

Однако этот метатег использовался до HTML 4. В HTML 5 мы используем метатег charset, как описано ниже.

<meta charset="UTF-8">

Эти метатеги предоставляют браузеру дополнительную информацию о кодировке документа. Браузер сначала просматривает атрибут Content-Type и декодирует документ в соответствии с кодировкой, указанной в значении атрибута. Если заголовок Content-Type отсутствует, будет использована кодировка по умолчанию.

Если браузер встречает один из вышеуказанных метатегов определения кодировки, он повторно проанализирует документ, используя предписанную схему кодирования.

Это также верно для внешних файлов JavaScript и CSS. Файлы JavaScript или CSS также можно кодировать по любой схеме кодирования. Мы можем использовать заголовок Content-Type, чтобы указать кодировку этих файлов.

Если заголовок ответа Content-Type отсутствует в ответе внешнего файла CSS, мы можем использовать правило @charset, чтобы указать кодировку файла в самом коде CSS.

@charset "utf-8";

Однако заголовок Content-Type или другие метаданные документа определяют кодировку файла документа, чтобы браузер мог проанализировать его на допустимую последовательность символов.

Однако в этой статье мы поговорим о кодировании символов с помощью некоторых инструментов, предоставляемых языком.

Кодировка символов в JavaScript

ASCII - одна из самых популярных кодировок, используемых до сих пор. Это схема кодирования 7-битной фиксированной длины, в которой для кодирования символа используется 7 бит. Эта кодировка позволяет кодировать только символы английского языка и некоторые часто используемые символы, такие как тире (-) и точка (.).

Однако движок JavaScript хранит строковые литералы в формате кодировки UTF-16. UTF-16 - это 16-битная схема кодирования с переменной длиной. UTF-16 может кодировать все символы в наборе символов Unicode с помощью 1 или 2 кодовых единиц.

Если вы читаете статью, о которой я упоминал ранее, то вы знаете, что такое кодовая единица. Единица кода - это строительный блок представления кодировки символа. Для UTF-16 единица кода - 16 бит. Если символу требуется больше памяти, он может добавить еще одну кодовую единицу, в сумме составляющую 32 бита.

Некоторые старые движки JavaScript могут использовать кодировку UCS-2. UCS-2 - это кодировка фиксированной длины, в которой для кодирования символа используется только 16 бит. Поскольку UCS-2 и UTF-16 используют набор символов UTF, их кодировка идентична.

Поскольку UTF-16 может использовать 16 или 32 бита для кодирования символа, он может кодировать больше символов, чем UCS-2, который использует только 16 бит. памяти на символ. Однако схема кодировки символов USC-2 устарела и устарела.

Более новые версии движка JavaScript используют схему кодирования UTF-16 для кодирования символов в строке. Начиная с ECMAScript 2015 (ES6), строковые литералы хранятся в кодировке UTF-16 и имеют полная поддержка UTF-16.

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

Для кодирования ASCII, поскольку у нас есть 7 бит для кодирования символа, всего можно закодировать 128 (2⁷) символов с помощью кодировки ASCII со значением от 0 на 127. Следовательно, кодовая точка символа находится в диапазоне от 0 до 127. Кодовая точка символа A - 65₁₀ или 41₁₆ .

Для кодировки UTF-16 мы можем закодировать символ в 16 бит или 32 бит. Если вы посмотрите на таблицу кодировки UTF-16, символы с кодовой точкой от 0₁₆ до FFFF₁₆ представлены 1 единицей кода ( 16 бит), а символы с кодовой точкой от 10000₁₆ до 10FFFF₁₆ представлены двумя кодовыми единицами (32 бита ).

В кодировке UTF код символа A равен 65₁₀ или 41₁₆, а символ - это код точка 906₁₆. Поскольку кодовая точка этих символов попадает в диапазон 0₁₆ - FFFF₁₆, их можно закодировать с помощью только одной кодовой единицы UTF-16. Следовательно, этот символ занимает всего 16 бит памяти.

Однако символы с кодовой точкой больше FFFF₁₆ требуют двух кодовых единиц. Например, символ смайлика 😊 (счастливое лицо) имеет кодовую точку 1F60A₁₆. Следовательно, для кодирования требуется две кодовых единицы или 32 бита памяти.

Когда для символа требуются две кодовые единицы, каждая кодовая единица называется суррогатной кодовой единицей, а вместе они называются суррогатными парами. Для символа 😊 суррогатная пара - D83D₁₆ DE0A₁₆.

Unicode Escape

Мы можем сохранить любой символ в одном, используя строковый литерал в JavaScript, то есть помещая символ или последовательность символов в строку в одинарных или двойных кавычках. JavaScript сохранит для нас эту строку в кодировке UTF-16.

Однако для представления символа можно также использовать кодовую точку символа. Для этого нам нужно использовать префикс \u, за которым следует шестнадцатеричное представление кодовой точки символа в схеме кодировки UTF-16. Префикс \u называется escape-символом Unicode.

Единица кода, представленная escape-символом Unicode, образует Unicode Escape. Следовательно, для символов, закодированных в одной кодовой единице UTF-16, Unicode Escape выглядит так, как показано ниже.

'\uXXXX'

Здесь XXXX - это точное четырехзначное шестнадцатеричное представление кодовой точки символа. В этом случае кодовая единица идентична кодовой точке.

Когда символы кодируются двумя кодовыми единицами, нам нужно два Unicode Escape для каждой суррогатной кодовой единицы.

'\uYYYY\uXXXX'

💡 Когда один или несколько уникальных escape-символов объединяются, они называются escape-последовательностью символов Юникода.

⦿ — — — — ⦿

Кодировка ASCII

Все символы с кодовой точкой от 0 (0₁₀) до 7F₁₆ (127₁₀) относятся к символу ASCII. набор. Поскольку эти символы кодируются только одной единицей кода UTF-16, нам нужен только один escape-код Unicode для представления этих символов по отдельности.

Например, для символа A с кодовой точкой 41₁₆ (65₁₀) его кодовая единица выглядит точно так же, как и его кодовая точка. Следовательно, его кодовая точка может быть представлена ​​как 0041₁₆. Его Unicode Escape довольно прост.

var characterA = '\u0041';
console.log( characterA ); // logs: A

Это относится ко всем символам из набора символов ASCII.

Если мы хотим представить только символы из набора символов ASCII и расширенного ASCII (типа ISO 8859–1), мы можем использовать префикс \x, который называется шестнадцатеричным escape-символом .

За \x следует однобайтовое шестнадцатеричное число из 2 точных символов, которое является кодовой точкой символа из набора символов Unicode. Следовательно, шестнадцатеричная escape-последовательность для символов A © имеет следующий вид.

console.log( '\x41\xA9' ); // logs: 

⦿ — — — — ⦿

Кодировка UTF

Символы UTF могут принимать одну или две кодовые единицы UTF-16. Следовательно, то, как мы пишем Unicode Escape, зависит от кодовой точки символа.

Для символа с кодовой точкой 906₁₆, поскольку он может быть закодирован только в одной кодовой единице, его escape-последовательность Unicode выглядит так, как показано ниже.

console.log( '\u0906' ); // logs: 

Для символа 😊 с кодовой точкой 1F60A₁₆ требуются две кодовые единицы UTF-16. D83D₁₆ и DE0A₁₆ - значения каждой кодовой единицы (16-битное число). Следовательно, escape-последовательность Unicode этого символа выглядит так, как показано ниже.

console.log( '\uD83D\uDE0A' ); // logs: 😊

Вы можете найти кодовые единицы символа UTF-16 с помощью онлайн-инструмента this. Однако работать с символом UTF-16 не всегда просто, поскольку нам необходимо заранее знать количество кодовых единиц, которые может принимать символ.

Кроме того, каждая кодовая точка должна быть ровно 4-значным шестнадцатеричным числом для представления в качестве уникального перехода. В противном случае JavaScript не сможет декодировать escape-последовательность, как показано в примере ниже.

console.log('\u41');
Error: Uncaught SyntaxError: Invalid Unicode escape sequence
console.log('\u0041');
A

ES6 предоставляет новый способ представления символа с помощью экранирования Unicode с использованием кодовой точки символа. Используя обозначение \u{}, символ можно представить с помощью его шестнадцатеричной кодовой точки.

console.log( '\u{41}' ); // logs: A
console.log( '\u{906}' ); // logs: 
console.log( '\u{1F60A}' ); // logs: 😊

⦿ — — — — ⦿

Смешанные персонажи

Уникальный Escape - это не что иное, как причудливый способ представить символ, используя информацию о кодировке символа. Следовательно, допустимо смешивать обычные символы в их закодированной (простой) форме с escape-последовательностью Unicode.

console.log( '\x41\u0020\uD83D\uDE0A\u0020\u006d\u0061\u006e' );
// A 😊 man
console.log( 'A \uD83D\uDE0A man' );
// A 😊 man
console.log( 'A \u{1F60A} man' );
// A 😊 man

💡 Вы можете проверить эту таблицу ASCII, чтобы узнать кодовые точки символов из набора символов ASCII. Или вы можете использовать этот набор символов UTF.

⦿ — — — — ⦿

Длина строки

В JavaScript мы используем свойство прототипа .length для строки, которая возвращает количество символов в строке.

console.log( 'Ab'.length ); // logs: 2

Однако это определение нас обмануло. На практике String.prototype.legth возвращает общее количество единиц кода UTF-16, используемых для кодирования строки. Это продемонстрировано в приведенном ниже примере.

console.log( '😊'.length ); // logs: 2

Поскольку для символа 😊 требуются две единицы кода UTF-16, мы получаем 2 как длину строки. В JavaScript нет встроенного метода для возврата длины строки с учетом Unicode.

Но с помощью оператора распространения ES6 легко исправить это, преобразовав символы в массив и получив его длину, как показано в приведенном ниже примере.

console.log( [ ...'😊'].length ); // logs: 1

Кодировка символов в HTML

То, как символы представлены в HTML, не имеет ничего общего с кодировкой JavaScript по умолчанию. Однако есть способ представить символ с помощью кодовой точки символа.

& - это специальный символ в HTML, однако разработчики обычно его игнорируют. Префикс &# зарезервирован для представления символа Unicode, и за ним должна следовать десятичная кодовая точка символа.

Однако мы можем использовать префикс &#x для представления того же символа, но с шестнадцатеричной кодовой точкой. Поскольку мы имеем дело только с кодовой точкой, в HTML нет концепции суррогатных пар.

💡 Если нам нужно напечатать символ & на экране, мы должны использовать &amp; нотацию, которая является стандартной для символа амперсанда.

&#65; <!-- character A -->
&#x41; <!-- character A -->
&#x1F60A; <!-- character 😊 -->
&#128522; <!-- character 😊 -->

Чтобы предоставить браузеру дополнительную информацию о кодировке документа, мы также должны добавить следующие метатеги. Однако современные браузеры оптимизированы для отображения символов UTF, несмотря на определение кодировки.

<html>
  <head>
    <meta charset="UTF-8">

💡 Кодировка веб-страницы HTML5 по умолчанию - UTF-8.

Однако HTML предоставляет некоторые псевдонимы для распространенных символов, например &amp; для символа & (амперсанд). Они называются экранированными символами, поскольку мы экранируем символы, которые в некоторых контекстах могут иметь другое значение.

&quot; <!-- character " -->
&amp; <!-- character &-->
&lt; <!-- character < -->
&gt; <!-- character > -->
&copy; <!-- character © -->

Вы можете следить за этой таблицей, чтобы узнать о других объектах HTML.

Кодировка символов в CSS

Мы также можем использовать escape-последовательность Unicode в CSS, но в этом случае мы не используем префикс \u. Мы можем использовать символ \, за которым следует шестнадцатеричное представление кодовой точки символа.

Обычно мы используем ::before и ::after псевдоэлементы для добавления текстового содержимого (, но не ограничиваясь) внутри элемента DOM. Мы используем свойство content селектора псевдоэлементов, чтобы ввести это строковое значение.

.some-elem::before {
  content: "\0041"; /* A */
  content: "\00A9"; /* © */
  content: "\0906"; /* आ */
  content: "\1F60A"; /* 😊 */
}

Подробнее о кодировке символов можно прочитать в этой статье.