# 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`可以寫成`a`(十進制)或者`a`(十六進制),字符`中`可以寫成`中`(十進制)或者`中`(十六進制),瀏覽器會自動轉換它們。
```html
<p>hello</p>
<!-- 等同于 -->
<p>hello</p>
<!-- 等同于 -->
<p>hello</p>
```
上面代碼中,字符可以直接表示,也可以使用十進制碼點或十六進制碼點表示。
注意,HTML 標簽本身不能使用碼點表示,否則瀏覽器會認為這是所要顯示的文本內容,而不是標簽。比如,`<p>`一旦寫成`<p>`或者`<p>`,瀏覽器就不再認為這是標簽了,而會當作文本內容將其顯示為`<p>`。
## 字符的實體表示法
數字表示法的不方便之處,在于必須知道每個字符的碼點,很難記憶。為了能夠快速輸入,HTML 為一些特殊字符,規定了容易記憶的名字,允許通過名字來表示它們,這稱為實體表示法(entity)。
實體的寫法是`&name;`,其中的`name`是字符的名子。下面是其中一些特殊字符,及其對應的實體。
- `<`:`<`
- `>`:`>`
- `"`:`"`
- `'`:`'`
- `&`:`&`
- `?`:`©`
- `#`:`#`
- `§`:`§`
- `¥`:`¥`
- `$`:`$`
- `£`:`£`
- `¢`:`¢`
- `%`:`%`
- `*`:`$ast;`
- `@`:`@`
- `^`:`^`
- `±`:`±`
- 空格:` `
注意,上面最后一個特殊字符是空格,它也有對應的實體表示法。
字符的數字表示法和實體表示法,都可以表示正常情況無法輸入的字符,逃脫了瀏覽器的限制,所以英語里面稱為“escape”,中文翻譯為“字符的轉義”。