问题描述
我可以使用什么事件侦听器来识别firefox-addon中来自hiddenDOMWindow(或其中的iframe)的请求?例如,在发送请求之前,我需要在http-on-modify-request事件中执行此操作。我试过:
- 注册全球http-上 - 修改 - 请求;但我无法区分源窗口
- 将侦听器添加到隐藏的DOM窗口本身;但我找不到任何before-load-event
- 将侦听器添加到hiddenDOMWindow.document; no before-load-event
- 将侦听器添加到创建的hiddenDOMWindow.document.iframe; no before-load-event
首先,您需要获取>
nsIChannel
:
DOMWindow
> function getDOMWindowFromChannel(ch){
var wp;
如果(ch.loadGroup&& ch.loadGroup.groupObserver){
wp = ch.loadGroup.groupObserver。
QueryInterface(Ci.nsIWebProgress);
}
} catch(ex){}
尝试{
if(!wp){
wp = ch.notificationCallbacks。
getInterface(Ci.nsIWebProgress);
$ b catch(ex){}
try {
if(wp){
return wp.DOMWindow ||空值;
}
}
catch(ex){}
return null;
$ b $现在你有一个DOMWindow
,你需要找到DOMWindow
的顶层窗口,这不是很直观:
function getToplevelWindow(win){
try {
return win.QueryInterface(Ci.nsIInterfaceRequestor)。
getInterface(Ci.nsIWebNavigation)。
QueryInterface(Ci.nsIDocShell)。
treeOwner。
QueryInterface(Ci.nsIInterfaceRequestor)。
getInterface(Ci.nsIXULWindow)。
docShell。
contentViewer.DOMDocument.defaultView;
}
catch(ex){
//可能已经是顶级窗口了。
回报胜利;
$现在,让工艺和安装观察者,把所有在一起:
函数观察(通道,主题,数据){
if(!(channel instanceof Ci.nsIChannel)){
return;
}
var win = getDOMWindowFromChannel(channel);
if(!win){
return;
}
var topWin = getToplevelWindow(win);
if(topWin.location.href.indexOf(chrome:// browser / content / hiddenWindow)!= 0){
return;
}
//做些东西,例如
console.log(topWin.location.href);
}
Services.obs.addObserver(注意,http-on-modify-request,false);
请注意,并非所有请求都是
nsIChannel
并不是所有的nsIChannel
实际上都有一个DOMWindow
或者真正的loadGroup
关联(例如后台请求),因此所有这些尝试catch
块。
另外,不要忘记在某些时候再次删除观察者,我跳过了。 ;)
最后,下面是一些代码来实际测试这个(我把所有东西都作为Scratchpad运行在about:newtab选项卡上,恰好有chrome权限就像附加组件一样):
var hw = Services.appShell.hiddenDOMWindow;
var iframe = hw.document.createElement(iframe);
hw.document.documentElement.appendChild(iframe);
var r = iframe.contentWindow.XMLHttpRequest();
r.open(GET,http://example.org/);
r.send();
What event-listeners can I use to identify requests originating from the hiddenDOMWindow (or an iframe within it) in a firefox-addon? I need to do this BEFORE the request has been sent, in the "http-on-modify-request" event, for example.
What I've tried:
- register for the global "http-on-modify-request"; but I can't distinguish the source window
- add listener to the hiddenDOMWindow itself; but I can't find any before-load-event
- add listener to the hiddenDOMWindow.document; no before-load-event
- add listener to the created hiddenDOMWindow.document.iframe; no before-load-event
解决方案First, you need to get a
DOMWindow
from annsIChannel
:function getDOMWindowFromChannel(ch) { var wp; try { if (ch.loadGroup && ch.loadGroup.groupObserver) { wp = ch.loadGroup.groupObserver. QueryInterface(Ci.nsIWebProgress); } } catch (ex) {} try { if (!wp) { wp = ch.notificationCallbacks. getInterface(Ci.nsIWebProgress); } } catch (ex) {} try { if (wp) { return wp.DOMWindow || null; } } catch (ex) {} return null; }
Now that you got a
DOMWindow
, you need to find the top level window for thatDOMWindow
, which is not really intuitive:function getToplevelWindow(win) { try { return win.QueryInterface(Ci.nsIInterfaceRequestor). getInterface(Ci.nsIWebNavigation). QueryInterface(Ci.nsIDocShell). treeOwner. QueryInterface(Ci.nsIInterfaceRequestor). getInterface(Ci.nsIXULWindow). docShell. contentViewer.DOMDocument.defaultView; } catch (ex) { // Likely already a top-level window. return win; } }
Now, lets craft and install the observer, bringing all together:
function observe(channel, topic, data) { if (!(channel instanceof Ci.nsIChannel)) { return; } var win = getDOMWindowFromChannel(channel); if (!win) { return; } var topWin = getToplevelWindow(win); if (topWin.location.href.indexOf("chrome://browser/content/hiddenWindow") != 0) { return; } // do stuff, e.g. console.log(topWin.location.href); } Services.obs.addObserver(observe, "http-on-modify-request", false);
It should be noted that not all requests are
nsIChannel
and not allnsIChannel
actually have aDOMWindow
or realloadGroup
associated (e.g. background requests), hence all thosetry catch
blocks.Also, don't forget to remove the observer again at some point, which I skipped. ;)
And lastly, here is some code to actually test this (I ran the whole thing as a Scratchpad on an about:newtab tab, which happens to have chrome privileges just like add-ons):
var hw = Services.appShell.hiddenDOMWindow; var iframe = hw.document.createElement("iframe"); hw.document.documentElement.appendChild(iframe); var r = iframe.contentWindow.XMLHttpRequest(); r.open("GET", "http://example.org/"); r.send();
这篇关于识别来自隐藏的DOM窗口(或其一个iframe)的请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!