# HTML 字符编码

## 简介

网页包含了大量的文字，浏览器必须知道这些文字的编码方法，才能把文字还原出来。

一般情况下，服务器向浏览器发送 HTML 网页文件时，会通过 HTTP 头信息，声明网页的编码方式。

```http
Content-Type: text/html; charset=UTF-8
```

上面代码中，HTTP 头信息的`Content-Type`字段先声明，服务器发送的数据类型是`text/html`（即 HTML 网页），然后声明网页的文字编码是`UTF-8`。

网页内部也会再用`<meta>`标签，再次声明网页的编码。

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

## 字符的数字表示法

网页可以使用不同语言的编码方式，但是最常用的编码是 UTF-8。UTF-8 编码是 Unicode 字符集的一种表达方式。这个字符集的设计目标是包含世界上的所有字符，目前已经收入了十多万个字符。

每个字符有一个 Unicode 号码，称为码点（code point）。如果知道码点，就能查到这是什么字符。举例来说，英文字母`a`的码点是十进制的`97`（十六进制的`61`），汉字“中”的码点是十进制的`20013`（十六进制的`4e2d`）。

由于下面的原因，不是每一个 Unicode 字符都能直接在 HTML 语言里面显示。

（1）不是每个 Unicode 字符都可以打印出来，有些没有可打印形式，比如换行符的码点是十进制的`10`（十六进制的`A`），就没有对应的字面形式。

（2）小于号（`<`）和大于号（`>`）用来定义 HTML 标签，其他需要用到这两个符号的场合，必须防止它们被解释成标签。

（3）由于 Unicode 字符太多，无法找到一种输入法，可以直接输入所有这些字符。换言之，没有一种键盘，有办法输入所有符号。

（4）网页不允许混合使用多种编码，如果使用 UTF-8 编码的同时，又想插入其他编码的字符，就会很困难。

HTML 为了解决上面这些问题，允许使用 Unicode 码点表示字符，浏览器会自动将码点转成对应的字符。

字符的码点表示法是`&#N;`（十进制，`N`代表码点）或者`&#xN;`（十六进制，`N`代表码点），比如，字符`a`可以写成`&#97;`（十进制）或者`&#x61;`（十六进制），字符`中`可以写成`&#20013;`（十进制）或者`&#x4e2d;`（十六进制），浏览器会自动转换它们。

```html
<p>hello</p>
<!-- 等同于 -->
<p>&#104;&#101;&#108;&#108;&#111;</p>
<!-- 等同于 -->
<p>&#x68;&#x65;&#x6c;&#x6c;&#x6f;</p>
```

上面代码中，字符可以直接表示，也可以使用十进制码点或十六进制码点表示。

注意，HTML 标签本身不能使用码点表示，否则浏览器会认为这是所要显示的文本内容，而不是标签。比如，`<p>`一旦写成`<&#112;>`或者`&#60;&#112;&#62;`，浏览器就不再认为这是标签了，而会当作文本内容将其显示为`<p>`。

## 字符的实体表示法

数字表示法的不方便之处，在于必须知道每个字符的码点，很难记忆。为了能够快速输入，HTML 为一些特殊字符，规定了容易记忆的名字，允许通过名字来表示它们，这称为实体表示法（entity）。

实体的写法是`&name;`，其中的`name`是字符的名字。下面是其中一些特殊字符，及其对应的实体。

- `<`：`&lt;`
- `>`：`&gt;`
- `"`：`&quot;`
- `'`：`&apos;`
- `&`：`&amp;`
- `©`：`&copy;`
- `#`：`&num;`
- `§`：`&sect;`
- `¥`：`&yen;`
- `$`：`&dollar;`
- `£`：`&pound;`
- `¢`：`&cent;`
- `%`：`&percnt;`
- `*`：`$ast;`
- `@`：`&commat;`
- `^`：`&Hat;`
- `±`：`&plusmn;`
- 空格：`&nbsp;`

注意，上面最后一个特殊字符是空格，它也有对应的实体表示法。

字符的数字表示法和实体表示法，都可以表示正常情况无法输入的字符，逃脱了浏览器的限制，所以英语里面称为“escape”，中文翻译为“字符的转义”。