标签仅语义化,不自动转义HTML;需先对内容做实体转义(如

用 <code> 标签展示 HTML 代码时,为什么内容还是被解析了
因为 <code> 本身只是语义化标签,不提供转义能力。浏览器仍会把里面未处理的 、<code>> 当成真实标签去解析——比如写 <code><div>hello</div>,结果页面上真冒出一个 <div> 元素,甚至执行 JS。
<p>常见错误现象:<code><code><script>alert(1)</script> 在页面中直接弹窗;<code><a href="javascript:alert(1)">click</a> 鼠标悬停就触发。
- 必须先对原始 HTML 字符串做实体转义(
→<code><,>→>,&→&) - 再把转义后的字符串塞进
<code>标签里,例如:<code><div>hello</div> - 别依赖
<pre class="brush:php;toolbar:false;"><code></code> 嵌套自动防转义——它只保留格式,不碰内容逻辑</li> </ul> <H3>用 <code>textContent</code> 替代 innerHTML 是最省心的方案</H3> <p>如果你只是想在页面上「显示一段 HTML 源码」,而不是渲染它,<code>textContent</code> 是零风险选择。它绕过 HTML 解析器,所有字符原样上屏。</p> <p>实操示例:</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p> <pre class="brush:php;toolbar:false;">const rawHtml = '<div class="box"><strong>test</strong></div>'; document.querySelector('code').textContent = rawHtml;</pre> <p>这样写,页面上就真显示 <code><div class="box"><strong>test</strong></div>这串字,不会生成 DOM 节点,也不会触发任何事件。- 适合文档、教程、控制台输出等纯展示场景
- 不支持语法高亮(除非配合 Prism.js 等库先设 textContent,再调用 highlightElement)
- 注意:不要混用——比如先用
textContent设值,又用innerHTML改同一元素,会覆盖并重新触发解析
需要语法高亮?先转义再交给高亮库
像 Prism.js、highlight.js 这类工具,输入的是「已转义的纯文本字符串」,不是原始 HTML。如果传进去的是未转义内容,它们内部可能误解析、漏着色,甚至引入 XSS 风险。
正确流程:
- 拿到用户或后端返回的原始 HTML 字符串(如
"<p><img src="x" onerror="alert(1)" alt="code标签防转义技巧_HTML代码片段安全展示" ></p>") - 用安全转义函数处理:例如
escapeHtml(rawHtml)→"<p><img src=x onerror=alert(1)></p>" - 把转义结果赋给
textContent或innerText,再调用Prism.highlightElement(codeEl)
别跳步:直接把原始字符串丢给
highlightElement,等于把 XSS 漏洞交到高亮库手上——它不负责安全过滤。服务端返回的 HTML 字符串,前端还用不用再转义
要看服务端是否已做 HTML 实体转义。如果后端返回 JSON 中的字段是
"<div>safe</div>",那前端可直接textContent显示;但如果返回的是"<div>unsafe</div>",就必须再过一遍转义逻辑。容易踩的坑:
- 后端用了
htmlspecialchars($str, ENT_QUOTES),但前端 JS 又用element.innerHTML = data.html—— 结果页面显示的是字面量<div>,而非预期结构 - 前后端都以为对方处理了,实际谁都没做;或者只对部分字段转义(比如 content 转了,title 没转)
- URL 参数、localStorage 读取的内容,一律视为原始输入,必须手动转义才能进
innerHTML
复杂点在于上下文混合:同一段数据可能既用于
textContent显示,又拼进href属性或onclick字符串里——这时候不能只做一次 HTML 转义,得按目标上下文分别处理。



















