【问题标题】:How to identify requests originating from the `hiddenDOMWindow`?如何识别来自“hiddenDOMWindow”的请求?
【发布时间】:2013-09-29 09:59:54
【问题描述】:

我可以使用哪些事件侦听器来识别来自 firefox 插件中的 hiddenDOMWindow(或其中的 iframe)的请求?例如,在“http-on-modify-request”事件中,我需要在发送请求之前执行此操作。

我尝试过的:

  • 注册全局“http-on-modify-request”;但我无法区分源窗口
  • 将监听器添加到 hiddenDOMWindow 本身;但我找不到任何加载前事件
  • 为 hiddenDOMWindow.document 添加监听器;没有加载前事件
  • 为创建的 hiddenDOMWindow.document.iframe 添加监听器;没有加载前事件

【问题讨论】:

    标签: javascript firefox firefox-addon httprequest


    【解决方案1】:

    首先,您需要从nsIChannel 中获取DOMWindow

    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;
    }
    

    现在你有了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) {
            // Likely already a top-level window.
            return win;
        }
    }
    

    现在,让我们制作和安装观察者,把所有东西放在一起:

    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);
    

    需要注意的是,并不是所有的请求都是nsIChannel,也不是所有的nsIChannel实际上都有一个DOMWindow或真正的loadGroup相关联(例如后台请求),因此所有这些try catch块。

    另外,不要忘记在某个时候再次删除观察者,我跳过了。 ;)

    最后,这里是一些实际测试的代码(我在 about:newtab 选项卡上将整个事情作为 Scratchpad 运行,它恰好具有 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();
    

    【讨论】:

      猜你喜欢
      • 2012-12-09
      • 2015-04-04
      • 2014-11-11
      • 1970-01-01
      • 1970-01-01
      • 2020-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多