模板字符串本身不防XSS,安全关键在于如何处理用户数据;未过滤的用户输入直接插入${}并赋值给innerHTML会导致XSS,应优先使用textContent显示纯文本。

模板字符串本身不防XSS,安全的关键不是“怎么写模板”,而是“怎么处理用户数据”。直接把未处理的用户输入放进${}里再塞进innerHTML,等于给攻击者开后门。
优先用 textContent 而不是 innerHTML
如果只是显示文字(比如用户名、评论内容、提示信息),根本不需要生成 HTML 字符串。直接赋值给textContent,浏览器自动当纯文本处理,、<code>&、" 全部原样显示,不会被解析成标签或脚本。
- ✅ 安全写法:
el.textContent = `欢迎,${userName}`; - ❌ 危险写法:
el.innerHTML = `<p>欢迎,${userName}</p>`;(哪怕 userName 看起来只是“张三”)
必须拼 HTML 时,先转义再插入
只有在确实需要动态生成带标签的结构(比如渲染一个用户头像+昵称卡片)时,才考虑模板字符串拼接。但前提是:所有来自用户的变量,都得提前做 HTML 实体编码。
立即学习“Java免费学习笔记(深入)”;
- 别手写正则替换,容易漏掉
'或 Unicode 变体 - 用浏览器原生方式最可靠:
document.createElement('div').textContent = str; return div.innerHTML; - 转义后才能放进模板:
<div class="card">${escapeHtml(name)}</div>
更推荐:用 DOM API 代替字符串拼接
比起拼一长串 HTML 字符串,用document.createElement + textContent + appendChild更清晰、更安全、也更容易维护。
- 创建元素:
const card = document.createElement('div'); - 设文本内容:
card.textContent = name;(自动安全) - 加类或属性:
card.className = 'user-card'; - 追加到页面:
container.appendChild(card);
富文本等特殊场景要另作处理
如果业务真要支持<b></b>、<p></p>这类格式(比如后台编辑器输出),模板字符串和简单转义都不够。这时应交由专业净化库(如 DOMPurify)处理,按白名单过滤标签和属性,而不是自己拼接或信任服务端返回的 HTML。
- 不要用
innerHTML = untrustedHtml - 不要用
v-html或dangerouslySetInnerHTML除非你完全掌控输入源 - 即使用了净化库,也要配合 CSP 响应头进一步限制脚本执行



















