HTML Sanitizer API 目前不可直接使用,必须同时满足三条件:确认浏览器支持(仅 Chromium 125+)、绕过 ESLint 报错(如全局声明或配置 globals)、运行于 HTTPS 环境(含 localhost 但不含 127.0.0.1),缺一则失效。

HTML Sanitizer API 目前不能直接用,得先确认浏览器支持、绕过 ESLint 报错、处理 HTTPS 限制,三者缺一不可。它不是开箱即用的函数,而是一个处于实验阶段的原生接口,现阶段在本地开发(http://localhost)大概率会静默失效。
为什么 new Sanitizer() 会报错或没效果
根本原因有三个,且常被混为一谈:
-
Sanitizer is not defined:ESLint 默认不认这个全局变量,TypeScript 类型定义也缺失,不是浏览器不支持,是工具链拦住了 -
typeof Sanitizer === 'undefined':真不支持——目前仅 Chromium 125+(Chrome/Edge 125+、Opera 111+)稳定启用,Firefox 和 Safari 仍为undefined - 调用了但 SVG/自定义元素消失、
onclick没被剥离:大概率运行在http://下,API 要求 HTTPS(含localhost但不含127.0.0.1),否则new Sanitizer()不报错但内部策略退化为极简模式
怎么让 Sanitizer() 在 React 里跑起来
别碰 polyfill,它不存在;也别依赖 Babel 插件,这玩意儿是浏览器原生能力。可靠路径只有两条:
- 开发阶段快速验证:在使用文件顶部加
/* global Sanitizer */,再加运行时检测 —— 这是唯一不改配置就能试的法子 - 团队项目长期用:在
.eslintrc.js的globals里加Sanitizer: 'readonly',同时确保webpack-dev-server或 Vite 启用 HTTPS(Vite 可配server.https: true) - React 渲染时别直接插
DocumentFragment,必须取fragment.innerHTML再塞进dangerouslySetInnerHTML,否则事件绑定、样式可能异常
setHTML() 和 sanitizeFor() 有什么区别
二者底层共用同一套策略,但调用位置和语义不同:
立即学习“前端免费学习笔记(深入)”;
-
element.setHTML(html, { sanitizer }):只能用于Element或ShadowRoot实例,是 DOM 方法,会自动清空原有子节点并注入净化后的内容;注意它不返回值,也不抛错,失败时静默回退 -
sanitizer.sanitizeFor('div', html):返回DocumentFragment,需手动提取.innerHTML;参数'div'表示“按<div>上下文解析”,影响内联样式、嵌套规则等,不是白名单开关 - 二者都受相同配置约束,比如
allowCustomElements: true对两者都生效;但setHTML()无法传入自定义配置对象,必须提前实例化带配置的Sanitizer
SVG 和自定义元素为什么还是被删了
即使你显式配置了 allowElements: ['svg', 'path'],仍有两个隐藏关卡:
- 协议关:当前所有实现(Chromium 125–128)强制要求页面加载于 HTTPS,
http://localhost:3000看似本地却满足条件,但http://127.0.0.1:3000或文件协议file://会直接禁用全部扩展能力,只保留基础标签过滤 - 上下文关:
sanitizeFor('span', svgString)会导致 SVG 解析失败(span不允许嵌套svg),必须用sanitizeFor('div', ...)或'body';setHTML()则取决于目标元素是否允许子元素为svg(如<p>就不行) - 没有 fallback:API 不提供“净化失败时返回原始字符串”的选项,出错就抛
DOMException,必须用try/catch包裹,不能假设它总成功
真正麻烦的不是怎么写那几行代码,而是判断此刻该不该用它——如果项目要兼容 Safari 或需要处理 http://127.0.0.1 开发环境,现在就该退回 DOMPurify;如果已锁定 Chrome 内部工具且走 HTTPS,那它比任何 JS 库都快、都省内存,但配置项稍不留意就会让 SVG 消失得毫无征兆。



















