Wla*_*ant 14 javascript firefox firefox-addon firefox4 prototype-programming
我正在研究如何从扩展中扩展Firefox弹出窗口阻止.一种选择是通过包装函数替换window.open()(或更确切地说Window.prototype.open())网页.一个重要的要求是网页无法检测或恢复此操作.例如,如果我只是这样做:
Window.prototype.open = wrapper;
Run Code Online (Sandbox Code Playgroud)
通过执行以下操作,网页可以轻松恢复更改:
delete Window.prototype.open;
Run Code Online (Sandbox Code Playgroud)
相反,我可以使用Object.defineProperty()来设置高级属性标志:
Object.defineProperty(Window.prototype, "open", {value: wrapper, configurable: false});
Run Code Online (Sandbox Code Playgroud)
网页无法再恢复此更改,但它仍然可以检测到它:delete Window.prototype.open通常会更改Window.prototype.open(看起来相同功能的不同实例)的值,这里delete根本不会产生任何影响.此外,Window.prototype.open = "test";delete Window.prototype.open;将产生不一致的结果(不同的结果取决于是否writable: false为属性指定了标志).
还有什么我可以做的来模仿原始属性的行为(没有使用二进制XPCOM组件,它有太多自己的问题)?
您可以尝试使用该nsIWindowWatcher界面注册您自己的窗口创建者(nsIWindowCreator).这样,您可以控制是否打开新窗口而不影响窗口对象本身(因此对网站保持不可见).
我不确定在window.open()没有这个可检测的情况下是否无法改变实现是一个错误.也许它不被认为是像这样的方法的重要要求Object.defineProperty.但是可能值得提出一个错误,看看其他人在将来考虑将其作为一种选择.毕竟,广告拦截是一个主要的用例.
最后我不得不放弃使用 JavaScript 代理来完成这项工作。尽管经过一些努力,我可以创建一个与window.open()原始函数完全相同的包装器(需要考虑错误 650299),但似乎没有合适的方法来替换原始window.open()函数。更改后的属性的行为总是与原始属性不同,这太糟糕了。
因此,我决定采用不同的方法作为弹出窗口阻止解决方案:监听content-document-global-created通知并查看主题(新窗口)及其开启者。具有非空开启器的窗口是某种弹出窗口。人们可以查看 URL 并决定是否应阻止弹出窗口。要阻止一个会调用window.stop()(在发送任何网络请求之前停止所有网络活动)和window.close(). 后者必须异步调用(有延迟),因为否则在窗口初始化继续时会导致崩溃。关于此方法的一些注意事项:
about:blank先加载,然后再更改为实际目的地。对于同源弹出窗口,后者不会发送新的content-document-global-created通知,这是不幸的。总而言之:不完美但可用。而且它非常简单,远不及 JavaScript 代理所需的代码量。
| 归档时间: |
|
| 查看次数: |
8757 次 |
| 最近记录: |