跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

如何利用 模板字符串 (Template Literals) 实现防 XSS 攻击的带标签函数解析

模板字符串本身不防XSS,但配合带标签函数可实现安全HTML插值;关键是对插值内容默认转义,遍历values做HTML实体编码(如<→ 模板字符串本身不防 XSS,但配合带标签函数(tagged template literals)可以实现安全的 HTML 插值 —— 关键在于**对插值内容做默认转义**,而非直接拼接。 带标签函数是防 XSS 的核心机制 标签函数接收模板字符串的静态部分(strings)和动态插值部分(values),你完全控制如何组合它们。默认行为是不做任何处理,但你可以主动对每个 values 做 HTML 实体编码: 遍历所有插值值,用
encodeURIComponent
或更合适的 HTML 转义函数(如转义
<
→
、"
→
"
等) 将转义后的值与静态字符串逐段拼接,确保用户输入永不被解析为 HTML/JS 避免使用
innerHTML
直接写入结果;推荐用
textContent
或
createTextNode
渲染纯文本,或用
insertAdjacentHTML
+ 严格校验白名单标签(进阶场景) 一个基础但有效的安全标签函数示例 下面是一个轻量、可复用的
html
标签函数,只对插值内容转义,保留模板中的原始 HTML 结构(静态部分):
function html(strings, ...values) { const escape = s => String(s) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); let result = strings[0]; for (let i = 0; i < values.length; i++) { result += escape(values[i]) + strings[i + 1]; } return result; } // 使用示例 const user = ''; const content = html`
Hello ${user}!
`; // →
Hello !
// 插入到页面时显示为纯文本,不会执行脚本
注意边界情况与增强方向 基础转义能防御大部分反射型/存储型 XSS,但需留意: URL 上下文需单独处理 :若插值用于
href
或
src
,仅 HTML 转义不够,应使用
encodeURI
或
encodeURIComponent
,并限制协议(如只允许
https:
、
mailto:
) 样式属性(style)需特殊过滤 :避免插入
javascript:
、
expression()
或未转义的
url()
内容;建议禁用内联 style,改用 CSS 类名控制 不信任静态字符串 :如果模板字符串本身来自用户输入(如后端返回的模板),那整个机制失效 —— 标签函数只保护 插值部分 ,静态部分必须可信 结合 DOM API 更安全 :最终渲染时优先用
element.textContent = …
或
document.createTextNode()
,比生成 HTML 字符串再
innerHTML
更可靠 生产环境推荐方案 不要从零手写安全函数。直接使用成熟库更稳妥: DOMPurify :对已生成的 HTML 字符串做白名单过滤(适合富文本) lit-html 或 hyperlit :编译期绑定 + 运行时自动转义,天然防 XSS React / Vue / Svelte :框架默认对 JSX / 模板插值做转义,只要不用
dangerouslySetInnerHTML
或
v-html
就很安全 自己实现标签函数适合学习原理或极简场景;真实项目请优先依赖经过审计的方案。

相关文章