应使用 DOMParser 解析 HTML 后清洗,而非正则;必须删除危险标签和事件属性,保留语义结构;需单独处理零宽字符和剪贴板污染;清洗策略须可配置、可绕过、可审计。

直接删 style 属性比正则安全,但仅删 style 不够——富文本粘贴进来的 HTML 还带着 onerror、data-*、align、零宽字符、 和嵌套 标签,这些都会污染 DOM 结构、干扰 CSS 选择器、破坏 SSR 一致性,甚至引发 XSS 风险。
为什么不能用 innerHTML.replace(/]*>/g, "") 清标签
这个正则看着快,实际踩坑极多:
- 匹配不到注释
、CDATA 段、自闭合标签里的换行或引号(比如)
- 会把
<script>console.log("x>y")</script>中的>当作标签结尾,直接截断 JS - 删完只剩扁平文本,丢失
、、等语义结构 - 对属性值里含
>或转义符(如")完全无感,极易漏删或错删
DOMParser + querySelectorAll 是唯一靠谱起点
必须先把字符串走标准解析路径,否则所有清洗都是空中楼阁:
- 用
new DOMParser().parseFromString(html, "text/html")得到文档对象,不操作原始 DOM - 查所有带危险属性的节点:
doc.querySelectorAll('*[onerror], *[onload], *[onclick], script, style, iframe, object') - 遍历用
for (const el of nodeList),不用forEach——DOM 变更时 NodeList 是活的,forEach会跳过动态插入/删除的节点 - 删
style用el.removeAttribute("style"),别用setAttribute("style", "")——空style属性仍会被[style]选择器命中
该留什么、该砍什么得按语义分级
不是“越干净越好”,而是保留可读性与结构信息:
- 必须删除:
<script></script>、、、、所有含on\w+的标签(如)- 建议删除:
、、、(除非它有白名单class,比如highlight)- 应保留:
、、–
、- /
- /
、(但需清理width/height,只留src和alt)style属性只放行白名单:text-align、margin-top/margin-bottom、max-width(仅限)零宽字符和剪贴板污染必须单独处理
Firefox/Edge 粘贴时带
\u200b、\u200c、\ufeff是常态,它们不显示,但会卡住textContent.trim()、让正则失效、导致移动端排版错乱:- 不要等它进 DOM 再清理——在
paste事件里就调event.preventDefault(),然后读event.clipboardData.getData("text/plain")而非"text/html" - 如果已污染,清空系统剪贴板:Windows 下执行
echo off | clip,macOS 下用printf "" | pbcopy - 后续文本处理加一层
.replace(/[\u200b-\u200f\u202a-\u202f\ufeff]/g, ""),别依赖trim()
真正难的不是删多少,而是判断哪些“脏”是业务需要的——比如微信公众号复制的
,删了就丢音频;又比如某些编辑器靠data-id维护内容锚点,一并清掉会导致协作崩溃。清洗逻辑必须可配置、可绕过、可审计,而不是写死成“一刀切”。 - 建议删除:
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











