如何在浏览器中捕获网站对window对象上第三方扩展注入接口的调用
实现思路
核心是通过方法劫持或者代理的方式,在不影响原有逻辑的前提下捕获调用信息,具体实现逻辑如下:
- 扩展注入时机需要设置为
document_start,确保你的脚本在第三方扩展注入自定义对象、网站调用对象方法前运行 - 由于浏览器扩展的content script运行在隔离上下文,无法直接操作页面对应的
window对象,需要将劫持逻辑注入到页面原生上下文执行 - 两种劫持方案适配不同场景:
- 提前监听对象注入:通过
Object.defineProperty监听window上对应属性的赋值,第三方扩展注入对象时立刻触发劫持逻辑 - 已挂载对象重写:如果第三方对象已经挂载到
window上,直接重写对象下的对应方法,插入捕获逻辑后再调用原方法返回结果
- 提前监听对象注入:通过
- 劫持逻辑需要保留原方法的执行上下文、入参和返回值,完全不影响原有业务的正常运行
代码示例
Chrome V3 扩展manifest.json配置
{ "manifest_version": 3, "name": "第三方扩展调用捕获", "version": "1.0", "content_scripts": [ { "matches": ["*://你要监控的特定网站域名/*"], "run_at": "document_start", "js": ["content.js"] } ] }
content.js代码(用于注入劫持逻辑到页面)
// 构造要注入页面的劫持脚本 const injectCode = ` let originalThirdPartyObj = null; const hookTargetMethod = () => { const target = window.thirdpartyextension; // 避免重复劫持 if (!target || target._hooked) return; // 这里以劫持doThis方法为例,需要捕获其他方法可以遍历所有属性重写 const originalDoThis = target.doThis; target.doThis = async function (...args) { // 捕获逻辑部分 console.log('捕获到doThis调用'); console.log('入参a:', args[0]); console.log('入参b:', args[1]); // 此处可插入你的自定义逻辑 // 执行原方法,原样返回结果,不影响原有逻辑 const res = await originalDoThis.apply(this, args); // 也可捕获返回值做处理 return res; }; target._hooked = true; }; // 监听第三方对象注入 if (window.thirdpartyextension) { hookTargetMethod(); } else { Object.defineProperty(window, 'thirdpartyextension', { configurable: true, enumerable: true, get: () => originalThirdPartyObj, set: (val) => { originalThirdPartyObj = val; hookTargetMethod(); return val; } }); } `; // 注入脚本到页面上下文 const scriptEl = document.createElement('script'); scriptEl.textContent = injectCode; document.documentElement.prepend(scriptEl); scriptEl.remove();
注意事项
- 若需要捕获该对象下的所有方法,可以遍历
window.thirdpartyextension的所有属性,对类型为function的属性逐一做重写即可 - 上述代码兼容同步/异步方法,若目标方法为同步方法,删除
async/await关键字即可正常使用 - Firefox扩展实现逻辑完全一致,仅需要调整manifest的对应字段适配Firefox平台规范即可
内容的提问来源于stack exchange,提问作者aste123
相关产品推荐
相关产品推荐

