sethtml()必须传入sanitizer实例,否则退化为不安全的innerhtml;它仅在chromium 123+和firefox 148+支持,且需先检测typeof sanitizer !== 'undefined',配合sanitizefor使用时容器类型影响过滤逻辑。

setHTML()必须传Sanitizer实例,否则等于innerHTML
直接写 el.setHTML(dirtyHtml) 是无效且危险的——它会退化成 innerHTML,所有 onerror、javascript:、<script></script> 都照常执行。浏览器只在你显式传入 sanitizer 实例时才启用过滤逻辑。
常见错误包括:
- 漏掉第二个参数:
el.setHTML(userContent)→ 立即触发 XSS - 误以为
setHTML自带默认 sanitizer,实际无默认值 - 用错对象:对 DocumentFragment 或文本节点调用
setHTML会报错,仅 Element 原型上有该方法
正确写法只有这一种:el.setHTML(dirtyHtml, sanitizer),且 sanitizer 必须是 new Sanitizer() 实例(或带配置的实例)。
兼容性检查不能靠 try/catch,必须 typeof Sanitizer !== 'undefined'
在 Safari 和 Firefox(除 148+)中,new Sanitizer() 会直接抛 ReferenceError: Sanitizer is not defined,JS 执行中断。try/catch 捕获不了语法级缺失,且掩盖了环境不支持的本质问题。
可靠检查方式只有一种:typeof Sanitizer !== 'undefined'。注意:
- 别写
window.Sanitizer—— 可能被污染或未定义 - ESLint 默认报
no-undef,需在文件顶部加/* global Sanitizer */或配置globals: { Sanitizer: 'readonly' } - 降级时建议返回原始字符串并
console.warn,而不是静默 fallback 到textContent(富文本会完全失效)
sanitizeFor() 返回 DocumentFragment,不是字符串
sanitizer.sanitizeFor('div', html) 返回的是 DocumentFragment,不是 HTML 字符串。直接赋给 innerHTML 会插入 [object DocumentFragment],页面空白。
两种安全用法:
- 取字符串再插入:
el.innerHTML = sanitizer.sanitizeFor('div', html).innerHTML(注意:只取内部 HTML,不含外层<div></div>) - 直接插入 DOM:
el.replaceChildren(sanitizer.sanitizeFor('article', html))(推荐,避免二次解析)
容器类型(如 'article'、'span')影响过滤行为:'span' 会剥离 <p></p> 等块级标签,'article' 则保留嵌套结构但严格过滤事件属性。
服务端仍需基础过滤,Sanitizer API 不是银弹
Sanitizer API 是客户端最后一道防线,不是替代服务端校验的理由。它不处理以下风险:
- CSS 中的
expression()、url(javascript:...)(当前浏览器策略已禁用,但旧版或自定义策略可能遗漏) - data URL 中的 base64 编码脚本(
data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==) - 服务端渲染模板中拼接的 HTML(
res.send(`<div>${userHtml}</div>`))
工程上必须做到:服务端至少移除 <script></script>、<iframe></iframe>、on* 属性和 javascript: 协议;前端再用 setHTML + Sanitizer 做二次净化。两者缺一不可。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











