用捕获阶段拦截paste事件更可靠,因其在编辑器冒泡处理前执行,可提前阻止或清洗恶意内容;示例中通过preventdefault+sanitizehtml实现安全粘贴。
在富文本编辑器中,可以通过 addeventlistener 的捕获阶段(usecapture = true)提前拦截 paste 事件,从而阻止或清洗恶意粘贴内容(如含危险 script 标签、onerror/onload 事件、iframe、javascript: 协议等)。关键在于“比编辑器自身的粘贴逻辑更早介入”,在内容还未插入 dom 前进行过滤。
为什么用 capture 阶段拦截更可靠
多数富文本编辑器(如 Quill、TinyMCE、Slate 或原生 contenteditable)会在冒泡阶段监听 paste 并执行默认粘贴逻辑。若你在冒泡阶段 preventDefault(),可能和编辑器逻辑冲突,甚至被覆盖;而捕获阶段能确保你的处理函数最先执行,真正“抢在编辑器之前”控制行为。
基础拦截与清洗示例(原生 contenteditable)
假设你的编辑器容器是 div#editor:
添加捕获型 paste 监听器:
const editor = document.getElementById('editor');
editor.addEventListener('paste', function (e) {
e.preventDefault(); // 必须先阻止默认行为
const clipboardData = e.clipboardData || window.clipboardData;
let html = clipboardData.getData('text/html') || '';
let text = clipboardData.getData('text/plain') || '';
// 若有 HTML,优先清洗 HTML;否则降级为纯文本
if (html) {
html = sanitizeHTML(html); // 自定义清洗函数(见下文)
} else {
html = text.replace(/\n/g, '<br>').replace(/ /g, ' ');
}
// 插入清洗后的 HTML(兼容 Safari/Chrome/Firefox)
document.execCommand('insertHtml', false, html);
}, true); // ← true 表示捕获阶段
简单但有效的 HTML 清洗策略
不依赖重型库(如 DOMPurify),可手动移除高危节点和属性:
- 用正则或 DOMParser 解析 HTML 字符串,再遍历清理
- 删除所有
<script></script>、<iframe></iframe>、<object></object>、<embed></embed>标签 - 移除所有以
on开头的属性(如onclick、onerror) - 过滤
href和src中的javascript:、vbscript:、 - 保留常用格式标签:
p, br, div, span, strong, em, ul, ol, li, a, img 等
注意兼容性与边界情况
某些浏览器(如旧版 Safari)对 clipboardData.getData('text/html') 支持有限,需 fallback 到 text/plain;document.execCommand 已废弃但目前仍是插入内容最兼容的方式;若使用现代编辑器框架(如 Slate),应优先查阅其插件机制(如 onPaste handler),仅在必要时退回到原生 capture 拦截。










