HTML 实体编解码

特殊字符与 & < 等 HTML 实体互相转换

HTML 实体编解码:什么时候必须转义,什么时候不必

编码与解码在做什么

编码把五个有语法意义的字符替换成实体。这五个字符就是"必须转义"的全部:

字符实体为什么必须转义
&&实体的起始字符,不转义会让后面的序列被误解析
<&lt;标签开始,不转义会破坏文档结构
>&gt;标签结束(单独出现时多数场景可省,但建议一起转)
"&quot;属性值定界符
'&#39;属性值也可能用单引号定界

解码是反方向:把实体形式还原成字符。除了上面这五个,还支持命名实体(如 &nbsp; &copy; &mdash;)和数字实体(十进制 &#169;、十六进制 &#xA9;,都表示版权符号)。工具的解码借助浏览器自身的解析引擎,所以对实体的支持范围与浏览器一致——这比自己维护一张实体表可靠。

什么时候必须转义

判断标准只有一条:这段文本会被放进 HTML 里当内容或属性值吗?

什么时候不必转义——以及为什么仍常被误用

场景是否需要说明
JSON 字符串内部不需要JSON 有自己的转义规则(\" \\),用 HTML 实体属于类型错误
URL 参数不需要用百分号编码(%26),不是 &amp;
纯文本文件、日志不需要没有 HTML 解析,转义只会让内容不可读
数据库存储不需要存原文,输出时按目标格式转义。这很重要——见下
CSV 单元格不需要CSV 有自己的引号规则

第四行是重点:不要"在入库时转义"。这个做法看起来安全,实际会造成三种麻烦:

  1. 双重转义。入库时转一次、输出时再转一次,用户看到的是 &amp;lt; 这种原始实体。
  2. 数据不可逆。存的是 &amp;,你就再也无法还原用户原本输入的是 &amp; 还是 &——两个不同的输入存成了同一个值。
  3. 非 HTML 用途被污染。同一份数据要导出成 CSV、发到 API、写进邮件,全部带着 HTML 实体。

正确原则是"存原文,按输出场景转义"。这也是现代模板引擎的默认行为(自动转义),所以用框架时通常什么都不用做——反而手动"加一层转义"是常见的 bug 来源。

常见症状对照

你看到的原因修法
&lt;div&gt; 显示在页面上转义了两次,或多转了一层找到重复转义的那一步,去掉一处
页面显示 &amp;存的是 &amp;,或入库时转义过清洗存量数据,改掉入库转义的做法
&amp; 出现在 JSON 里用 HTML 实体代替了 JSON 转义改用 JSON 转义工具
复制的内容带 &nbsp;从网页复制时带出了实体解码一次;注意 &nbsp;(U+00A0)与普通空格不是同一个字符,去重和比较时可能出问题

最后一行的细节值得记住:不换行空格(U+00A0)不是普通空格。它看起来一样,但在字符串比较、正则 \s(在部分实现里不匹配它)、以及粘贴进代码时都会造成"看起来没问题但就是不对"的故障。用空白处理工具统一替换成普通空格是常见做法。

工具怎么用

编码按钮处理上面列的五个必须转义字符;解码按钮还原上述五类实体(含命名与数字形式)。全程在浏览器本地完成。

常见问题

编码会处理所有字符吗?

会转义 & < > " ' 五个在 HTML 中具有特殊含义的字符,其余字符原样保留,避免破坏显示。

解码支持数字实体吗?

支持。解码借助浏览器解析,{ 等十进制、十六进制实体以及命名实体都能正确还原。