标签不自动转义,需手动对&、、"、'五字符实体编码,否则浏览器会解析为html语法,导致内容错位或xss。

<code> 标签本身不自动转义内容,它只是语义化标记“一段代码”,但里面若含 &、、<code>> 等字符,浏览器仍会按 HTML 规则解析——结果就是标签被吃掉、内容错位,甚至触发 XSS。
为什么 <code> 里直接写 <div> 会出问题
<p>因为 <code><code> 是普通 HTML 元素,不是沙箱。浏览器在解析时看到 就准备开新标签,根本不管它在不在 <code><code> 里。
- 写
<code><div></div> → 渲染出一个空 <div>,而不是字符串 <code><div>
<li>写 <code><code>price & tax → & 被当实体起始符,后面没合法名(如 amp;),可能截断或报错
- 用户输入含
<script>alert(1)</script>,直接塞进 <code> 就执行
正确做法:先转义,再放进 <code>
必须对原始字符串做 HTML 实体转义,再放入 <code>,且推荐配合 <pre class="brush:php;toolbar:false;"></pre> 保留格式。
- 只转义五个基础字符:
& → &(必须最先)、 → <code>、<code>> → >、" → "、' → '
- 顺序不能错:先
&,否则 可能被误认为 <code> 实体的一部分
- 服务端 PHP 用
htmlspecialchars($str, ENT_QUOTES, 'UTF-8');Node.js 推荐 he.encode(str, { useNamedReferences: true })
- 前端 JS 动态处理时,别手写正则链,用浏览器原生逻辑更稳:
const el = document.createElement('div'); el.textContent = raw; return el.innerHTML;
JS 动态插入时,textContent 和 innerHTML 怎么选
想安全显示原始代码字符串,就别碰 innerHTML ——除非你已确保内容 100% 转义完毕。
- 往
<code> 元素设内容,优先用 el.textContent = escapedString,完全规避解析风险
- 若需保留换行/缩进,
textContent 本身支持,再加 CSS white-space: pre-wrap 即可
- 千万别
el.innerHTML = rawString,哪怕 rawString 看起来“只是代码”——用户输入不可信
- React/Vue 中,
{'<code><div>'} 或 <code>{{ '<code><div>' }} 会原样输出,但这是框架插值机制在转义;若用 <code>dangerouslySetInnerHTML 或 v-html,传入值必须是已转义的字符串,且不能重复转义
最常被忽略的一点:前后端协作时,API 返回的 HTML 字符串如果已是转义态(比如 <div>),前端再调一次 he.encode() 或拼接 <code>,就会变成双层编码,页面显示 <div> 而不是 <div>。约定好“传输不转义、展示层负责”比补救更省事。</div>
<code><div></div> → 渲染出一个空 <div>,而不是字符串 <code><div>
<li>写 <code><code>price & tax → & 被当实体起始符,后面没合法名(如 amp;),可能截断或报错<script>alert(1)</script>,直接塞进 <code> 就执行
正确做法:先转义,再放进 <code>
必须对原始字符串做 HTML 实体转义,再放入 <code>,且推荐配合 <pre class="brush:php;toolbar:false;"></pre> 保留格式。
- 只转义五个基础字符:
&→&(必须最先)、→ <code>、<code>>→>、"→"、'→' - 顺序不能错:先
&,否则可能被误认为 <code> 实体的一部分 - 服务端 PHP 用
htmlspecialchars($str, ENT_QUOTES, 'UTF-8');Node.js 推荐he.encode(str, { useNamedReferences: true }) - 前端 JS 动态处理时,别手写正则链,用浏览器原生逻辑更稳:
const el = document.createElement('div'); el.textContent = raw; return el.innerHTML;
JS 动态插入时,textContent 和 innerHTML 怎么选
想安全显示原始代码字符串,就别碰 innerHTML ——除非你已确保内容 100% 转义完毕。
- 往
<code>元素设内容,优先用el.textContent = escapedString,完全规避解析风险 - 若需保留换行/缩进,
textContent本身支持,再加 CSSwhite-space: pre-wrap即可 - 千万别
el.innerHTML = rawString,哪怕 rawString 看起来“只是代码”——用户输入不可信 - React/Vue 中,
{'<code><div>'} 或 <code>{{ '<code><div>' }} 会原样输出,但这是框架插值机制在转义;若用 <code>dangerouslySetInnerHTML或v-html,传入值必须是已转义的字符串,且不能重复转义最常被忽略的一点:前后端协作时,API 返回的 HTML 字符串如果已是转义态(比如
<div>),前端再调一次he.encode()或拼接<code>,就会变成双层编码,页面显示<div>而不是<div>。约定好“传输不转义、展示层负责”比补救更省事。</div>











