跳到主要内容

HTML 实体编码到底在转什么:& < > " ' 与 &lt; 的来龙去脉

讲清楚 HTML 实体编码把 & < > 双引号单引号转成 &lt; 这类写法的原因,为什么它能挡住 XSS 和标签被浏览器解析,以及命名实体和数字实体怎么选,在代码展示和邮件里又怎么用。

发布于 作者 李雷
#HTML 实体 #HTML 转义 #XSS #前端安全 #编码

HTML 实体编码到底在转什么:& < > " ' 与 &lt; 的来龙去脉

写网页的人迟早会撞上一个问题:你明明想在页面上显示一段 <div> 标签,结果浏览器把它当真的元素吃掉了,屏幕上什么都没有。或者更糟,你把用户填的内容原样塞进页面,有人填了一段脚本,页面就替他执行了。这两件事的解法是同一个:HTML 实体编码。

HTML 实体编码就是把对浏览器有特殊含义的字符,换成一串以 & 开头、; 结尾的转义写法。浏览器读到这串写法时,知道它代表的是字面字符,而不是结构标记。最常见的就是把 < 写成 &lt;

五个必须记住的预定义实体

绝大部分场景,你只需要处理五个字符。它们是 HTML 语法里有特殊地位的字符,转义后才能安全地当文本显示:

  • & 转成 &amp;,这是所有实体的起始符号,自己也得转,否则后面的实体会被连读
  • < 转成 &lt;,标签的左尖括号
  • > 转成 &gt;,标签的右尖括号
  • " 转成 &quot;,双引号属性的边界
  • ' 转成 &#39;,单引号属性的边界

很多人只转 <> 就以为够了,这是个坑。如果属性用单引号写成 value='it's',里面那个没转义的单引号会直接把属性截断。五个字符一个都不能少。Toolora 的 HTML 实体编码工具 默认就是这五个一起处理,非 ASCII 的中文和 emoji 原样保留,因为现代 HTML 在 UTF-8 下显示它们是安全的。

一个真实的输入输出例子

假设你在写教程,想让读者看到字面的标签:

输入:

<div class="card">

编码后输出:

&lt;div class=&quot;card&quot;&gt;

把这串结果直接放进文章的 HTML 源码,浏览器渲染出来,读者看到的就是 <div class="card"> 这行文本本身,而不是一个被解析掉、什么都看不见的空 div。三个字符各归各位:左尖括号成了 &lt;,右尖括号成了 &gt;,两个双引号成了 &quot;

为什么这能防 XSS

XSS,也就是跨站脚本攻击,最经典的形态是:网站把用户提交的内容直接拼进页面,而用户提交的是一段脚本。比如评论框里有人填:

<script>alert(1)</script>

如果你不做处理就回显到页面,浏览器会把这段当成真的 <script> 标签执行。先过一遍编码,它变成:

&lt;script&gt;alert(1)&lt;/script&gt;

此时浏览器只把它当普通文字显示,尖括号不再开启标签,脚本就跑不起来了。漏转 <script> 是反射型 XSS 的头号根源,而这五个字符的转义就能挡掉其中绝大部分。需要补充一句:实体编码管的是 HTML 文本上下文,如果内容要进 onclick=href= 这种属性,你还得额外做 JS 或 URL 转义,光实体编码挡不住 javascript: 这类 URL。涉及 URL 那一层时可以配合 URL 编码工具 一起处理。

命名实体和数字实体的分工

同一个字符常常有两种写法。& 可以写成命名实体 &amp;,也可以写成数字实体 &#38;(十进制)或 &#x26;(十六进制)。两者渲染出来完全一样,区别在可读性和覆盖面:

命名实体更好认,&amp; 一眼就知道是和号,适合手写和阅读。但命名实体只有有限的一批字符有,生僻字符未必有对应的名字。数字实体则能表示任意字符,只要给出它的码点,所以它的覆盖面是全的。实践中的惯例是:能用命名就用命名,没有命名再退回数字。Toolora 的编码器就是这个策略,优先输出命名实体,遇到没有命名的字符才落到数字引用。

解码与双重转义的那点细节

我自己第一次被双重转义绊住,是从一个 CMS 里复制商品描述,粘出来满屏的 &amp;eacute;&amp;mdash;。当时一头雾水,以为数据坏了。后来才想明白:这是被转义了两次。里层本来是 &eacute;,它里面的 & 又被转成了 &amp;,于是变成 &amp;eacute;

解码的规则很干净:一次只拆一层。把 &amp;amp; 解码一次,得到 &amp;,再解一次才是字面的 &。这是有意为之,套了几层就解几次,正好对得上。所以遇到双重转义的内容,解码一次让 &amp; 塌回 &,那些被压住的 é、破折号、右单引号就还原了,邮件预览或正文读起来才正常,而不是满屏的 &amp;

在代码展示和邮件里的常见用途

把这些拼起来,日常会反复用到实体编码的场景其实就几类:在博客或文档里原样展示一段代码标签;在把用户输入回显到页面前做安全转义;还原从富文本编辑器或邮件系统里复制出来、被多重转义的内容;以及让一段带引号和尖括号的字符串安全穿过 JSON 和 HTML 两层模板,不在第一个 " 处被截断。

最后提醒一个最容易犯的错:不要对已经转义过的文本重复编码。把 &amp; 再编一次会得到 &amp;amp;,层层叠加越编越乱。原则是只在输出那一刻编码一次,数据存储和中间传递阶段保持原文。想顺手处理代码片段里的引号、反斜杠之类转义,可以用 字符串转义工具 搭配着来。

理解了字符的特殊含义和这套转义规则,实体编码就不再是玄学,而是一个你随手能验证的确定操作。


Made by Toolora · Updated 2026-06-13