事件捕获阶段仅适用于click等dom事件,而fetch、localstorage、copy等敏感操作不经过dom事件流,故addeventlistener捕获模式无效;真正有效的拦截需通过劫持全局api、proxy代理或浏览器扩展实现。

不能靠事件捕获阶段做全局敏感操作拦截——它只管 DOM 事件,而敏感操作(如 fetch 外发、localStorage 写入、copy 文本、document.execCommand 截图触发)大多不经过 DOM 事件流。
为什么 addEventListener 捕获模式对敏感操作无效
事件捕获阶段(useCapture = true)仅适用于可冒泡/可捕获的原生 DOM 事件,比如 click、keydown、input。但真正危险的操作往往绕过 DOM:
-
fetch/XMLHttpRequest是纯 JS API,不触发任何事件 - 复制文本可能走
document.execCommand('copy')或Clipboard.writeText(),后者甚至需要用户手势,不暴露给事件监听器 - 文件下载、
iframe导航、postMessage跨域通信都不在事件流中 - 即使监听
beforeunload,也无法阻止已发起的异步外发请求
真正能拦截的入口只有三个:全局函数劫持、代理对象、浏览器扩展 API
想在逻辑执行前干预,必须替换或包裹原始行为,而非监听事件:
- 劫持
window.fetch和window.XMLHttpRequest.prototype.send:检查url、body、headers是否含敏感词或目标域名 - 用
Proxy包裹localStorage/sessionStorage的setItem方法,校验键名和值内容 - 重写
navigator.clipboard.writeText,加入同步内容扫描(注意:需在安全上下文且有用户手势) - 若需拦截截图类行为(如
html2canvas渲染),只能靠Object.defineProperty封禁关键 canvas 方法或检测document.hidden+performance.now()异常高频调用
Chrome 扩展是唯一可靠方案,但需明确权限边界
纯前端 JS 无法拦截所有敏感路径;生产环境真正落地的方案,是通过 manifest.json 声明权限后,在扩展 content script 中实现:
- 用
chrome.webRequest.onBeforeRequest监听并阻断外发请求(支持匹配 URL、method、requestBody) - 用
chrome.storage.local存敏感词库,比前端内存更难被绕过 - 配合
chrome.runtime.sendMessage向页面注入防护逻辑,但不能直接访问页面 DOM —— 需用executeScript注入沙箱脚本 - 注意:
activeTab权限下无法拦截后台请求;要拦截所有请求,必须声明"webRequestBlocking",且用户安装时会看到明确提示
真正难的不是“怎么拦”,而是“拦住之后怎么不破坏业务”。比如劫持 fetch 后若同步扫描 body,会阻塞整个请求链路;而异步上报又可能漏掉已发出的数据。这类权衡点,往往比技术实现本身更决定方案成败。











