# 前端常见的几种"转义"/"编码"的辨析
## 前言
从来没有任何一个场景, 比Web前(后)端涉及到更多的字符编码问题. **"编码"(encode)** 一词又常和 **"转义"(escape)** 混淆, 导致本来就复杂的问题变得更加复杂. 因此有必要在此整理出常��的几种 编码/转义 情景, 使用无歧义的名称, 并给出其他正确名称, 以作区分.
## 辨析
|情景|正确名称|如将|转为|描述|
|:---|:---|:--:|:--:|:---|
|JS字符串转义| |`\n`|`[CR][LF]`|JS字符串中适用, 与其他编程语言类似, 以`\`为转义标识|
|HTML转义|**字符实体** / HTML Escape|`<`|`<`|用来规避HTML对某些字符的特定渲染行为|
|URI(URL)编码(转义)|URI(URL) Encode(Escape)|`啊`|`%E5%95%8A`|常见于传输中, 替换非ASCII等不安全字符为字节码. 对中文一般使用UTF-8编码|
|Unicode编码|Unicode Encode|`啊`|`\u554a` 或 `%u554a`|将字符替换为Unicode字符集编号, 可全部替换, 也可仅替换不安全字符. Unicode表示法也是用来表示特殊字符的一般方法|
|字符编码转换|iconv / encode|(GBK)`啊`-`0xB0A1`|(UTF-8)`啊`-`0xE5958A`|将文字内容从一种编码转为另一种编码. 二进制实际内容发生改变, 但文字显示结果不变|
|字符解码转换|decode|(GBK)`0xB0A1`-`啊`|(UTF-8)`0xB0A1`-`(乱码)`|将文字内容的解码方案从一种编码转为另一种编码, 二进制实际内容不变, 文字显示结果改变|
`啊`在Unicode字符集中的编号为`0x554A`, 在UTF-8编码中为`0xE5958A`, 在GB系列编码中为`0xB0A1`, 因此有了上表中的表现.
另外, 将`[空格]`替换为`+`或`%20`**都是**URI转义, `+`常见于Query String中, `%20`常见于URI其它部分中.
## 总结
处理字符串的 编码/转义 时, 总体上应该优先考虑不影响程序行为的, 人为规定的转换(URI转义, Unicode编码), 其次再考虑字符编码上的转换(UTF-8/GB2312), 最后再考虑影响程序行为的转换——即真正的"转义"(反斜杠, 字符实体).
如果某个地方提供了对"字符编码"的转换, 一定要搞清楚它转变的是编码方案(二进制数据改变, 显示的字不变), 还是解码方案(二进制数据不变, 显示的字改变), 否则易使数据损坏(在解码方案错误时编码会造成丢字, 甚至锟斤拷).
除了中文版Windows系统不可避免地保留系统ANSI编码(GB)而带来的转换外, 在其他地方要尽可能多使用 UTF-8 编码, 典型的其他编码如GB系列和 ISO 8859-1 则尽量不要使用.
关于可用的字符实体列表, 参考[此处](https://www.w3school.com.cn/tags/html_ref_entities.html)及其后与字符相关的手册.
关于UTF-8和Unicode的区别, 参考[这篇文章](https://www.zhihu.com/question/23374078/answer/65352538).