未定义JavaScript-addEventListener
我正在创建一个阻止广告的chrome扩展。到目前为止,一切都很好。我的目标是:未定义JavaScript-addEventListener,javascript,google-chrome,google-chrome-extension,ecmascript-6,ecmascript-2016,Javascript,Google Chrome,Google Chrome Extension,Ecmascript 6,Ecmascript 2016,我正在创建一个阻止广告的chrome扩展。到目前为止,一切都很好。我的目标是: 禁用WebSocket 禁用控制台日志 禁用警报 禁用弹出窗口(窗口。打开) 在卸载之前禁用on 当然,它应该只在指定的网站上阻止这些功能。我搜索了如何阻止函数。我发现使用扩展禁用函数的唯一方法是 在manifest.json中添加一个内容脚本init.js,该脚本将在document\u start处运行(这将防止在我的扩展代码之前执行任何其他代码,因此在我禁用这些函数之前,没有人可以窃取并保存对它们的引用) 从i
WebSocket
警报
窗口。打开
)on
manifest.json
中添加一个内容脚本init.js
,该脚本将在document\u start
处运行(这将防止在我的扩展代码之前执行任何其他代码,因此在我禁用这些函数之前,没有人可以窃取并保存对它们的引用)init.js
在网页中插入代码,以便我的扩展可以访问非沙盒环境addEventListener
之外的所有函数。为了阻止onbeforeunload
,我应该向它添加一个代理处理程序,并跟踪调用以检查侦听器名称是否为onbeforeunload
。我写了以下脚本:
addEventListener = new Proxy(addEventListener, {
apply: (f, t, args) => {
if(args[0] !== 'onbeforeunload'){
f.apply(t, args);
}
}
});
这将筛选调用,并仅允许未设置onbeforeunload
事件的调用。但是,它抛出引用错误:未定义addEventListener。这让我很吃惊。我想这可能是因为addEventListener
尚未在document\u start
初始化,而是console.log(addEventListener的类型)将函数
记录到控制台。这怎么可能呢
我无法解释。但是,我尝试将其放入一个函数中,然后对该函数执行requestAnimationFrame
,直到addEventListener
变得可访问为止(我在try…catch
中重新封装了上述代码)。但是,事实证明,修改addEventListener
总是抛出ReferenceError,而仅仅访问不会抛出错误
我还尝试从开发者控制台和javascript:…
方法访问它,但它的行为正常,我可以修改它而不会出现任何错误
编辑
当然,问题与不同,因为我正确地将脚本注入了非沙盒(真实)页面环境,并且我可以访问真实的窗口
对象。addEventListener
实际上不是全局的,而是间接的。它是EventTarget.prototype
(至少在Chrome中)的一个属性<代码>窗口的原型链中有EventTarget.prototype
,这使得addEventListener
成为一个全局变量
因此,您需要粗略地代理它(无需检查事件名称,仅用于演示):
const save=EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener=新代理(保存{
应用:函数(目标、此参数、参数){
console.log(“Foo!”);
返回save.apply(thisArg,args);
}
});
document.body.addEventListener(“单击”,函数(){
控制台日志(“单击”);
});代码>
…addEventListener
实际上不是全局的,而是间接的。它是EventTarget.prototype
(至少在Chrome中)的一个属性<代码>窗口
的原型链中有EventTarget.prototype
,这使得addEventListener
成为一个全局变量
因此,您需要粗略地代理它(无需检查事件名称,仅用于演示):
const save=EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener=新代理(保存{
应用:函数(目标、此参数、参数){
console.log(“Foo!”);
返回save.apply(thisArg,args);
}
});
document.body.addEventListener(“单击”,函数(){
控制台日志(“单击”);
});代码>
…
我不知道您这样做是否会遇到问题,也不知道您的整体方法是否会起作用(祝您好运!),但这就是为什么您会在addEventListener
…-)中遇到错误的原因还有一个问题。您如何解释修改addEventListener
会在定义时抛出ReferenceError
,我可以访问它,但不能修改它?@jumpjet\uuuuu我不确定您为什么会得到这样的结果。当我在普通的Chrome窗口中尝试它时,我不知道。顺便说一句,我之前没有想到,addEventListener
是全局的,因为window
继承了EventTarget.prototype
:-)但是分配给窗口
的版本并不能处理任何地方的更新。我不知道这样做是否会遇到问题,也不知道您的整体方法是否有效(祝您好运!),但这就是为什么您在addEventListener
…-)上出现错误的原因还有一个问题。您如何解释修改addEventListener
会在定义时抛出ReferenceError
,我可以访问它,但不能修改它?@jumpjet\uuuuu我不确定您为什么会得到这样的结果。当我在普通的Chrome窗口中尝试它时,我不知道。顺便说一句,我之前没有想到,addEventListener
是全局的,因为window
继承了EventTarget.prototype
:-)但是分配给窗口的版本将无法在任何地方更新它。为什么要禁用sockets和console.log?@DanielHerr。许多网站通过WebSockets
以image:data
的形式传输广告。斯坦达