直接用matches不能过滤粘贴内容,真正起作用的是监听paste事件+解析剪贴板html+遍历dom节点+域名比对白名单+移除外链标签或属性。

直接用 matches 本身不能过滤粘贴内容——它只是 DOM 元素的判断方法,比如 element.matches('a[href]') 用来检测是否匹配某选择器。真正起作用的是富文本编辑器(如 Quill、UEditor、TinyMCE)或自定义粘贴事件中结合 clipboard 模块或 paste 事件 + 正则/DOM 遍历来清洗内容。
明确目标:什么是“带外链样式的标签”
这类标签通常指:
-
<a href="https://xxx.com">...</a>—— 明确指向站外域名的链接 -
<img src="https://cdn.other-site.com/...?x-oss-process=image/resize,p_40">—— 外部图片资源 -
<iframe src="http://third.com/embed"></iframe>—— 外部嵌入内容 - 含
target="_blank" rel="noopener"但 href 仍是外链的 a 标签(SEO 风险点)
在粘贴时实时过滤:监听 paste 事件 + 清洗 DOM
不依赖编辑器插件时,可手动拦截粘贴行为,解析剪贴板 HTML,移除外链相关节点:
- 用
e.preventDefault()阻止默认粘贴 - 调用
e.clipboardData.getData('text/html')获取原始 HTML 字符串 - 创建临时
div,innerHTML = htmlStr解析为 DOM 树 - 遍历所有
a、img、iframe元素,用element.matches('a[href]')判断是否存在 href;再用new URL(element.href).host或正则提取域名,对比白名单 - 对确认为外链的元素:移除整节点,或清空
href/src属性,或替换为站内跳转(如/link?url=xxx) - 最后把清洗后的
div.innerHTML插入编辑区域
Quill 编辑器专用方案:用 clipboard.matchers
Quill 支持通过 clipboard.matchers 自定义粘贴规则。以下代码可清除所有外链 a 标签,保留内链和纯文本:
clipboard: {
matchers: [
['a', (node, delta) => {
const href = node.getAttribute('href');
if (!href) return delta;
try {
const url = new URL(href);
// 只保留同源链接(含 www 与非 www 统一处理)
const allowedHosts = ['yourdomain.com', 'www.yourdomain.com', location.host];
if (allowedHosts.includes(url.host)) {
return delta; // 保留
}
} catch (e) {}
// 外链:返回空 delta,即丢弃该节点
return new Delta();
}]
]
}
UEditor / 自研富文本:服务端+前端双保险
仅靠前端无法保证安全,建议配合后端过滤:
- 前端粘贴时用正则粗筛:
html.replace(/<a>]+href=["']https?:\/\/(?!(?:www\.)?yourdomain\.com)[^"']*["'][^>]*>/gi, '')</a> - 提交前,后端用
Jsoup(Java)、DOMDocument(PHP)或cheerio(Node.js)二次校验并清理 - 重点过滤:
<a></a>的 href、<img>的 src、<script></script>、<iframe></iframe>、<style></style>等高风险标签
核心逻辑不是靠 matches 单独工作,而是把它作为清洗过程中的一个判断环节。真正过滤靠的是事件拦截 + DOM 操作 + 域名比对 + 白名单机制。实操中建议优先使用编辑器原生 clipboard 扩展能力,再辅以服务端兜底。











