绝大多数情况下不用转义;utf-8 页面中中文、emoji、©、€等unicode字符可直接写入html内容或属性值,浏览器能正确解析渲染,仅在非utf-8环境才需数字编码。

HTML里中文、emoji、©这些字符要转义吗?
绝大多数情况下不用。UTF-8 页面中,中文、emoji、©、€ 等 Unicode 字符可直接写入 HTML 文本内容或属性值,浏览器能正确解析和渲染。唯一例外是:当输出目标不是 UTF-8(比如旧邮件模板、某些嵌入式设备 HTML 渲染器),才需强制用 ★ 或 ★ 这类数字编码。
容易踩的坑:
• 误把中文当成“特殊字符”反复转义,导致页面显示 中文 而非“中文”
• 在已声明 <meta charset="UTF-8"> 的页面里,对 © 手动替换成 © —— 多余且降低可读性
• 混淆“传输编码”和“展示编码”:API 返回的 JSON 字段值如果是 "title": "用户说 > 5",前端直接插进 innerHTML 就行,不必再 encode 一遍
innerHTML 插入前必须做 HTML 转义,但别用 encodeURIComponent
encodeURIComponent 是为 URL query string 设计的,它把 变成 <code>%3C,把空格变成 %20,这些在 HTML 中不会被自动还原,直接插入会显示乱码,不是安全转义。
正确做法只有两种:
• 简单场景:用临时 DOM 元素借浏览器原生逻辑const temp = document.createElement('div'); temp.textContent = userInput; const safeHtml = temp.innerHTML;
• 生产环境:用成熟库如 he.encode()(Node.js)或 DOMPurify.sanitize()(含白名单过滤)
• 绝对禁止:element.innerHTML = encodeURIComponent(str) —— 这等于把用户输入变成一串 URL 编码文本,毫无语义
服务端模板渲染时怎么避免双重转义?
像 Django、Jinja、EJS、Vue(v-html)、React(dangerouslySetInnerHTML)这类机制,默认会对变量做一次 HTML 转义。如果你传入的已经是转义后的字符串(比如 <p>hello</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/shouce/1862" title="使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件"><img
src="https://img.php.cn/upload/manual/000/000/010/170901721079108.gif" alt="使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/shouce/1862" title="使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件" class="overflowclass">使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件</a>
<p class="overflowclass">如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Andr​​oid友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Andr​​oid应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更</p>
</div>
<a rel="nofollow" href="/xiazai/shouce/1862" title="使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>),再转一次就变成 <p>hello</p>,页面上显示的是源码而非渲染效果。
关键判断点:
• 查看 API 响应体:如果后端返回的 HTML 字段值里已经含 ,前端就不要再调 <code>he.encode()
• Vue 中 v-html 接收的必须是原始 HTML 字符串,不是已转义字符串
• Node.js 使用 he.encode(htmlStr, { useNamedReferences: true }) 可读性更好,但仅用于“从原始字符串生成安全 HTML”这一环节
• 最容易忽略的是:前后端约定不清,同一字段在 API 层被 encode 一次,在模板层又被 autoescape 一次
哪些字符真得转义?顺序为什么不能错?
只这五个:&、、<code>>、"、'。其中 & 最危险 —— 它是所有实体的起始符,未转义的 &id=1&name=test 可能被截断成 &id=1 后丢数据。
正则替换顺序必须是:
• 先 & → &
• 再 → <code><br>• 再 <code>> → >
• 最后引号
原因:如果先换 ,而原始字符串含 <code>,就会变成 <code><,双重编码。
复杂点在于:属性值中 ' 和 " 的处理取决于你用哪种引号包裹属性 —— title='用户写了 " ' 里双引号不用转,但单引号必须转;反之亦然。所以实际工程中,建议统一用双引号写 HTML,并把 " 和 ' 都转义,省去判断成本。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










