如何实现Chrome Extension遍历网页全部文本内容搜索匹配敏感词的功能
Chrome扩展网页敏感词扫描技术实现方案
前置扩展配置
首先在manifest.json中完成基础权限和注入规则配置,manifest v3版本示例如下:
{ "manifest_version": 3, "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content-script.js"], "run_at": "document_idle" } ], "permissions": ["activeTab"] }
所有文本扫描、匹配逻辑都在注入页面的content-script中实现。
1. 页面文本节点遍历方案
优先选择TreeWalker而不是手动递归遍历DOM,前者是浏览器原生实现,遍历效率是手动实现的3-5倍,且不会触发页面重排
- 过滤script、style、输入框等非用户可见内容的文本节点,避免误匹配代码字符串、干扰用户输入
- 核心实现代码:
const skipTags = new Set(['SCRIPT', 'STYLE', 'NOSCRIPT', 'IFRAME', 'INPUT', 'TEXTAREA']); const walker = document.createTreeWalker( document.body, NodeFilter.SHOW_TEXT, { acceptNode: node => { if (skipTags.has(node.parentElement.tagName) || node.textContent.trim() === '') { return NodeFilter.FILTER_SKIP; } return NodeFilter.FILTER_ACCEPT; } } ); // 收集所有符合要求的文本节点 const textNodes = []; let currentNode; while (currentNode = walker.nextNode()) { textNodes.push(currentNode); }
2. 敏感词匹配方案
根据敏感词库规模选择对应匹配逻辑:
- 敏感词量级小于1000条:使用正则匹配,注意提前转义敏感词中的特殊字符避免正则注入
// 正则特殊字符转义方法 const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // 构造全局匹配正则 const sensitiveWords = ['敏感词1','敏感词2','敏感词3']; const matchReg = new RegExp(sensitiveWords.map(escapeRegExp).join('|'), 'gi');
- 敏感词量级大于1万条:实现轻量AC自动机做多模式匹配,遍历一次文本即可匹配所有敏感词,时间复杂度仅和文本长度相关,和敏感词数量无关
- 匹配过程中记录每个命中结果在对应文本节点中的起始、结束偏移量,用于后续屏蔽、高亮操作。
3. 动态页面内容适配
针对SPA、无限滚动、异步加载等动态更新的页面内容,使用MutationObserver监听DOM变化做增量扫描:
const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { // 处理新增DOM节点 mutation.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE && !node.classList.contains('扩展自定义忽略类名')) { // 仅扫描新增节点下的文本,无需全页面重扫 scanSingleNode(node); } }); // 处理原有文本节点的内容修改 if (mutation.type === 'characterData') { scanSingleNode(mutation.target); } }) }); observer.observe(document.body, { childList: true, subtree: true, characterData: true });
4. 性能优化要点
- 对DOM变化监听做100ms节流,批量处理频繁的节点更新,避免占用过多主线程资源导致页面卡顿
- 敏感词匹配逻辑放入Web Worker执行,CPU密集型运算不会阻塞页面渲染
- 命中敏感词后的替换操作,采用拆分文本节点包裹标签的方式实现,不要直接修改原节点的textContent,避免破坏原页面的事件绑定
内容的提问来源于stack exchange,提问作者Scollier
相关产品推荐
相关产品推荐

