【发布时间】:2017-04-20 16:22:29
【问题描述】:
我正在创建一个用于屏蔽广告的 chrome 扩展程序。到目前为止,一切都很好。我的目标是:
- 禁用
WebSocket - 禁用
console.log - 禁用
alert - 禁用弹出窗口 (
window.open) - 禁用
onbeforeunload
当然,它应该只在指定的网站上阻止这些功能。我搜索了如何阻止功能。我发现使用扩展禁用功能的唯一方法是
- 在
manifest.json添加一个内容脚本init.js,它将在document_start运行(这将防止任何其他代码在我的扩展程序代码之前执行,因此在我禁用它们之前没有人可以窃取和保存对这些函数的引用) - 来自
init.js在网页中注入代码,让我的扩展可以访问非沙盒环境 - 覆盖列入黑名单的函数
我什么都做了,但问题是如何覆盖函数。我在 EcmaScript7 规范中发现 无法检测函数是否为代理实例。所以,我代理了这些功能中的每一个,它按预期工作。网站无法注意到我已经覆盖了所有这些功能。
但是,它适用于除addEventListener 之外的所有功能。为了阻止onbeforeunload,我应该向它添加一个代理处理程序并跟踪调用以检查侦听器名称是否为onbeforeunload。我写了以下脚本:
addEventListener = new Proxy(addEventListener, {
apply: (f, t, args) => {
if(args[0] !== 'onbeforeunload'){
f.apply(t, args);
}
}
});
这应该过滤调用并只允许未设置onbeforeunload 事件的调用。但是,它会抛出 ReferenceError: addEventListener is not defined。这让我很惊讶。我想这可能是因为 addEventListener 尚未在 document_start 初始化,但 console.log(typeof addEventListener) 将 function 记录到控制台。这怎么可能?
我无法解释。但是,我尝试将其放入函数中,然后将 requestAnimationFrame 放入该函数,直到 addEventListener 变得可访问(我也将上述代码封装在 try...catch 中)。但是,事实证明,修改 addEventListener总是抛出 ReferenceError,而只是访问它从不抛出错误。
我也尝试从开发者控制台和javascript:... 方法访问它,但它运行正常,我可以修改它而不会出现任何错误。
编辑
当然,问题不像this one,因为我将脚本正确注入到非沙盒(真实)页面环境中,并且我可以访问真实的window 对象。
【问题讨论】:
-
为什么要禁用sockets和console.log?
-
@DanielHerr。许多网站以
image:data到WebSockets传输广告。标准adBlock将永远无法阻止它们。所以,我决定创建自己的扩展。
标签: javascript google-chrome google-chrome-extension ecmascript-6 ecmascript-2016