DOMPurify必须显式配置白名单并禁用style/class等危险属性,服务端需jsdom模拟环境,且前后端须双重净化;禁止javascript:/data:协议,清除Word粘贴残留,语义标签应保留而不可控样式须归零。

富文本编辑器输出的 HTML 通常夹杂大量冗余标签、内联样式、不可靠 class 名和危险属性(比如 javascript: 协议),直接存入数据库或渲染到前端会引发 XSS 风险、样式冲突、SEO 损害和 SSR 渲染异常。必须做针对性净化,不能只靠简单白名单过滤。
用 DOMPurify 做基础 XSS 防御,但默认配置不够用
DOMPurify 是目前最可靠的客户端/服务端 HTML 净化库,但它默认放行 style 标签和大量内联 CSS 属性(如 color、font-size),而 CMS 富文本常滥用这些导致样式失控。服务端使用时(如 Node.js),需显式关闭 ALLOWED_TAGS 和 ALLOWED_ATTR 的宽松模式。
- 禁用
style标签:传入{ USE_PROFILES: { html: true }, ALLOWED_TAGS: [] }并手动补全你需要的语义化标签(如['p', 'h2', 'ul', 'li', 'strong', 'em']) - 禁止所有内联样式:设置
FORBID_ATTR: ['style'],否则<p style="margin:0">会绕过净化 - 拦截
javascript:和data:协议:确保FORBID_CONTENTS: [/javascript:/i, /data:/i]生效(注意正则全局标志)
去除 Word 粘贴残留的 class 和 span 嵌套
用户从 Word 或网页复制内容进富文本编辑器后,常生成类似 <span class="Apple-converted-space"> </span> 或多层嵌套 <span><span><span>文字</span></span></span>。这类结构既无语义又难维护,DOMPurify 默认不清理它们。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 在净化前先用正则预处理:匹配并扁平化连续
<span>(但保留带语义的class="highlight"这类业务约定) - 用
cheerio(Node)或DOMParser(浏览器)遍历 DOM,移除空span、仅含空白字符的节点、以及不含任何有效属性的class(如class="MsoNormal") - 避免用
innerHTML.replace()直接删class——会误杀<div class="card-header">这类业务 class
保留语义但剥离不可控样式:用 sanitizeHtml 替代简单 stripTags
很多团队用 stripTags(html, ['p', 'br']) 这类函数粗暴删标签,结果把 blockquote、figure、pre 全干掉,破坏内容结构。真正需要的是「语义保留 + 样式归零」。
立即学习“前端免费学习笔记(深入)”;
- 用
sanitizeHtml库(非DOMPurify)配置allowedTags列表,明确放开['blockquote', 'figure', 'figcaption', 'pre', 'code'] - 对允许的标签统一重置样式:在净化后插入
<style>p, h2, blockquote { margin: 1em 0; font-size: 1rem; }</style>,而不是依赖原始 inline style - 特别注意
img:必须强制要求src为相对路径或白名单域名(如^https?://(cdn\.example\.com|images\.example\.com)/),否则src="data:image/png;base64,..."可能撑爆内存
真正麻烦的不是过滤什么,而是定义「哪些 HTML 是业务可接受的语义」——比如是否允许 table?colgroup 是否算安全?这些决策得和产品、前端、安全团队对齐,写进 CMS 的编辑规范里,而不是只靠代码兜底。


















