首页 > 文章 > 开发运维 > HTML转义后又多了amp?先核对重复编码,再看反转义顺序

HTML转义后又多了amp?先核对重复编码,再看反转义顺序

HTML实体转义

点击使用相关工具

去使用

一段原本想展示为代码的标签,保存以后却出现了<p>;再次处理,又冒出<。这通常需要先辨认数据中的真实字符,而不是继续点“转义”。HTML实体转义工具可以用小样本检查这类变化,但它的反转义有固定替换顺序,不能凭点击次数推断数据经过了几层编码。

先留住原文,再做一次往返

把下面一行粘到“输入文本”,点击“转义 (HTML → 实体)”。输入的是尖括号和一个普通的&号,不是标签的网页截图:

<p>A&B</p>

输出应为:

&lt;p&gt;A&amp;B&lt;/p&gt;

把这份输出复制回输入框,点击“反转义 (实体 → HTML)”,应还原为<p>A&B</p>。输出区仍然显示完整标签文本,不会只显示段落内容A&B。工具用文字方式呈现结果,并没有把你的标签当作HTML执行或预览。

本页的转义只改五类字符:&、小于号、大于号、双引号和单引号,依次对应&amp;、&lt;、&gt;、&quot;、&#039;。中文、空格和斜杠不会因此全部变成实体;这里也不是把文件重新保存成另一种字符编码。

还要分清复制的位置。浏览器正在显示的正文、查看源码时的字符序列和数据库字段里的原值,可能不是同一份文字。看到页面上的尖括号,不等于源数据里一定存着尖括号。用工具复现时,应记下粘贴来源并保留原字符串,避免把浏览器已经显示过的结果当成后台原始值。

第二次转义,增加的是实体开头的&

仍以上面的第一次输出为输入,再点一次“转义”,会得到:

&amp;lt;p&amp;gt;A&amp;amp;B&amp;lt;/p&amp;gt;

原先的&lt;是一串以&开头的文字,再次转义时,这个&变成&amp;,后面的lt;仍然保留,因此多出了amp;。本页一次转义先处理原文中的&,再处理尖括号等字符,不会在同一轮把刚生成的&lt;再次转义;重复来自你又把已转义的结果送回了输入。

排查真实页面时,应分别留存原始输入、保存后的数据和最终输出,确认哪一步把实体当成普通文本又编码了一次。不要为了让眼前的文字好看,就全局删除amp;或所有&号,正常网址参数和正文中的&也可能被一起改坏。

反转义不是严格的“一次剥一层”

下面几条要逐条放入输入框,分别点击“反转义”,不要连着点击后把旧结果当作新输入:

输入文字本页输出文字
&amp;lt;<
&amp;amp;lt;&amp;lt;
&#65; &#x41;A A
&nbsp; &apos;&nbsp; &apos;

第一条一次就得到小于号,是因为本页先把&amp;替换为&,再处理&lt;,后一步看到了前一步刚露出的序列。第二条却仍留下实体文字,因为同一轮&替换不会反复扫描刚生成的内容。不同片段可能因此表现不同,不能把“解了几次”直接当作“原来转了几次”的证据。

表中的&#65;和&#x41;分别是十进制与十六进制数字引用,都对应字母A。相反,&nbsp;与&apos;虽然是HTML里的命名引用,本页没有对应的命名替换,结果会保持原样。它不是完整HTML实体解析器,也不能把超出单个UTF-16码元范围的数字引用当作完整Unicode码点正确还原;例如不要用它验证表情的数字引用。

未变化也不等于格式正确。本页不提供完整的实体合法性诊断,少写分号、名称不在替换表中或输入了别的编码,都可能留下原文。连续点击反转义而不更换输入框,处理的仍是同一段输入,并不会自动把上一次输出继续解码。只有明确把输出复制回去,才开始了新的转换;需要保留的字面实体也可能在这一步被改变。

还原后能直接作为安全HTML发布吗?

不能。反转义会恢复尖括号和引号,工具并不删除脚本、事件属性或危险链接,也不能替代目标系统的安全过滤与输出处理。展示文本、HTML属性、脚本字符串和网址各有不同规则;本页输出区只显示文字,不代表把结果放入另一个网站也不会执行。先确认数据来源和使用位置,再由目标系统按其规则处理。

如果手里的是%3Cp%3E这样的百分号序列,应去URL编码/解码核对;整段JSON中的引号和反斜杠,则先用JSON格式化工具检查结构。只改输入框不会自动刷新输出,切换样本或方向后需要重新点击相应按钮,再比较新结果。

立即使用HTML实体转义