html转义本质是将、&、"、'五字符替换为对应实体,防止解析错误和xss;须按上下文选方案:服务端用内置函数全转义,前端优先textcontent,json嵌入需先stringify再html转义,禁用url编码替代。

HTML转义本质就是处理特殊字符
HTML转义不是独立功能,它直接对应 、<code>>、&、"、' 这五个字符的编码替换。浏览器解析 HTML 时,一旦遇到这些字符且未被转义,就会误认为是标签或属性边界,导致结构错乱或 XSS 漏洞。
比如原始字符串 "user<script>alert(1)</script>" 如果不转义就直接插入 DOM,<script></script> 会被执行;而转义后变成 "user<script>alert(1)</script>",纯文本显示,无害。
不同场景下该用哪种转义方式
服务端和客户端的转义策略不能混用,核心区别在于「谁在解析」和「何时解析」:
- 服务端输出 HTML 模板(如 PHP
htmlspecialchars()、Pythonhtml.escape()):必须对所有用户输入做完整转义,且默认使用ENT_QUOTES或等效参数,确保"和'都被覆盖 - 前端 JS 动态插入内容(如
element.innerHTML = data):绝不能依赖服务端转义兜底,必须用textContent替代innerHTML;若真需插 HTML,先用DOMPurify.sanitize(),而不是手写正则替换 - JSON 嵌入 HTML(如
<script>var data = <%= json %></script>):不能只做 HTML 转义,必须用JSON.stringify()序列化后再 HTML 转义,否则引号和反斜杠会破坏 JS 语法
常见错误:把 URL 编码当 HTML 转义用
encodeURIComponent() 和 encodeURI() 是给 URL 路径/参数用的,不是 HTML 转义方案。它们不会处理 或 <code>>,反而会把空格变成 %20、中文变成 %E4%B8%AD,直接塞进 HTML 里会导致页面显示一堆百分号。
典型翻车现场:
document.getElementById('msg').innerHTML = encodeURIComponent('<div>hello</div>');
结果页面显示:%3Cdiv%3Ehello%3C%2Fdiv%3E,完全不是预期效果。
正确做法只有两个:
- 纯文本展示 → 用
textContent - 需要渲染 HTML → 先由可信来源生成,再经
DOMPurify过滤,而非靠编码函数“凑合”
自定义转义函数容易漏掉 ' 和 Unicode 变体
很多人手写正则替换,比如 str.replace(/, '<').replace(/>/g, '>'),看似覆盖了主要符号,但实际有三个硬伤:
- 没处理
&本身 —— 若原字符串含,先替再替 <code>&会导致,最终显示为文字而非空格 - 忽略单引号
'—— 在属性值用单引号包裹时(title='O'Reilly'),不转义会导致 HTML 解析中断 - 无视 Unicode 等价字符 —— 如全角<>、零宽空格、BOM 字符,它们不会被常规正则捕获,却可能绕过过滤逻辑,尤其在富文本粘贴场景中高频出现
真正安全的做法是依赖语言内置函数(如 PHP 的 htmlspecialchars($str, ENT_QUOTES | ENT_SUBSTITUTE))或成熟库(如 JS 的 he.escape()),它们已覆盖全部边缘 case。
最常被跳过的细节是:转义必须在**最终输出到 HTML 文档流之前一刻**完成,早了可能被二次编码,晚了可能已进入不可控上下文。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











