
HTML 转义字符显示为原始文本而不是渲染效果
常见现象是页面上直接看到 、<code> 这类字符串,而不是对应的 或空格。本质是浏览器把转义序列当作了普通文本,没触发 HTML 解析。
根本原因通常是:你用 JS 赋值给 innerText 或 textContent,或者服务端返回的字符串被框架(如 React/Vue)自动做了二次转义。
- 用
innerHTML替代innerText可让浏览器解析转义字符,但注意 XSS 风险——只对可信内容用 - React 中写
{'<div>'} 会原样输出,得用 <code>dangerouslySetInnerHTML={{__html: '<div>'}} <li>Vue 模板里用 <code>v-html,而非双大括号插值 - 后端返回 JSON 时如果已转义过一次(如 Python 的
html.escape()),前端再手动拼接就容易叠成 -
html.escape('<script>')→'<script>'</script>(安全存入 HTML 上下文) -
html.unescape('<p>Hello World</p><div class="aritcle_card flexRow"> <div class="artcardd flexRow"> <a class="aritcle_card_img" href="/xiazai/skill8272" title="anything-to-html"><img src="https://img.php.cn/upload/skill/000/000/081/179195588450431.jpg" alt="anything-to-html" ></a> <div class="aritcle_card_info flexColumn"> <a href="/xiazai/skill8272" title="anything-to-html">anything-to-html</a> <p>将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。</p> </div> <a href="/xiazai/skill8272" title="anything-to-html" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div>')→'<p>Hello World</p>'(准备渲染) - 注意:
html.unescape()不处理 Unicode 实体(如😊),需额外用codecs.decode(s, 'unicode_escape')
Python 里 html.unescape() 和 html.escape() 怎么选
处理用户输入或存储 HTML 内容时,html.escape() 是防 XSS 的第一道关;读取并展示时,html.unescape() 才能还原成可渲染的符号。
典型误用:从数据库读出带 " 的字段,直接塞进模板,结果引号不显示——其实该先 html.unescape()。
立即学习“前端免费学习笔记(深入)”;
JS 中 decodeURIComponent() 不能替代 HTML 转义解码
很多人看到 %26lt; 就下意识用 decodeURIComponent(),但它只解 URL 编码,不是 HTML 实体。混用会导致 变成 <code>< 还是乱码,取决于原始编码层级。
真正要解 HTML 实体,浏览器环境最稳的是临时 DOM 元素法:
function htmlUnescape(str) {
const div = document.createElement('div');
div.innerHTML = str;
return div.textContent || div.innerText || '';
}
- 不要用正则手动替换
等——实体有上百种,还有十进制 <code>、十六进制 <code> - Node.js 环境可用
he库:const he = require('he'); he.unescape(' -
DOMParser也可,但比临时 div 开销大,没必要
富文本编辑器保存后显示异常: 消失或变成空格
编辑器(如 TinyMCE、Quill)默认把连续空格转成 存储,但前后端传输或模板渲染时若忽略空白处理规则,就会塌陷。
关键点在于:CSS 的 white-space 属性和 HTML 解析行为必须匹配。
- 存库前确保用
html.escape()(Python)或DOMPurify.sanitize()(JS)保留,别被过滤掉 - 渲染时容器加 CSS:
white-space: pre-wrap;,否则浏览器把当普通空格合并 - 检查是否在 JS 中用
.trim()或正则/\s+/g处理过内容——会干掉对应的 Unicode 字符\u00a0
实体转义不是“一劳永逸”的开关,它嵌在输入、存储、传输、渲染四个环节里,漏掉任意一层, 就可能变成看不见的坑。

















