本文介绍了尝试从Firefox插件(SDK)中的资源加载内容时出现安全性错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用SDK创建一个Firefox插件。我的目标很简单,拦截一个特定的iframe,并加载我自己的HTML页面(与我的插件打包为一个资源),而不是最初请求的内容。
$ b

远远我有以下代码:

  var httpRequestObserver = 
{
观察:函数(主题,主题,数据)
{
var httpChannel,requestURL;

if(topic ==http-on-modify-request){
httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
requestURL = httpChannel.URI.spec;

var newRequestURL,i;

if(/someurl/.test(requestURL)){
var ioService = Cc [@ mozilla.org/network/io-service;1\"].getService(Ci.nsIIOService );

httpChannel.redirectTo(ioService.newURI(self.data.url('pages / test.html'),undefined,undefined));
}

return;
}
}
};

var observerService = Cc [@ mozilla.org/observer-service;1\"].getService(Ci.nsIObserverService);
observerService.addObserver(httpRequestObserver,http-on-modify-request,false);

这段代码的工作原理是它检测到正确的iframe加载并正确执行重定向。但是,我得到以下错误:
$ b

如何解决这个限制?

解决方案

我真的在想这个。



当我改用loadContext时,它已经解决了。现在,当你得到loadContext的时候,你得到了任何浏览器元素(标签浏览器,或者框架或者iframe)的contentWindow,然后像正在做的那样放弃http请求,然后 loadContext.associatedWindow.document.location = self .data('pages / tests.html');



完成

在这里粘贴代码删除所有的私人东西。你可能需要使用chrome.manifest来测试它,并将代码粘贴到这里。
$ b $ pre $ Cu.import('resource:// GRE /模块/ Services.jsm');

var httpRequestObserver = {
观察:函数(主题,主题,数据){
var httpChannel,requestURL;

if(topic ==http-on-modify-request){
httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
requestURL = httpChannel.URI.spec;

var newRequestURL,i;

if(/someurl/.test(requestURL)){
var goodies = loadContextGoodies(httpChannel);
if(goodies){
httpChannel.cancel(Cr.NS_BINDING_ABORTED);
goodies.contentWindow.location = self.data.url('pages / test.html');
} else {
//不要做任何事情,因为没有与httpChannel相关的contentWindow,可能是一个谷歌广告正在加载或一些Ajax调用什么的,所以这不是一个错误
}
}

return;
}
}
};
Services.obs.addObserver(httpRequestObserver,http-on-modify-request,false);





//这个函数从httpChannel的loadContext获取contentWindow和其他好东西
函数loadContextGoodies(httpChannel){
// httpChannel必须是在第8行httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);上完成的对于nsiHTTPChannel的http-on-modify-
//启动loadContext的东西
var loadContext;
尝试{
var interfaceRequestor = httpChannel.notificationCallbacks.QueryInterface(Ci.nsIInterfaceRequestor);
// var DOMWindow = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow); //不再做,因为:https://developer.mozilla.org/en-US/docs/Updating_extensions_for_Firefox_3.5#Getting_a_load_context_from_a_request //改为在
下面加载loadContext试试{
loadContext = interfaceRequestor.getInterface(Ci.nsILoadContext);
} catch(ex){
try {
loadContext = subject.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext); (!loadContext){
// no load context(
)catch(ex2){}
}
} catch(ex0){}

所以不要做任何事情,尽管你可以运行这个,这是你的旧代码
//这可能意味着它加载一个ajax调用或像谷歌广告的事情
返回null;
} else {
var contentWindow = loadContext.associatedWindow;
if(!contentWindow){
//这个频道没有窗口,它可能会加载资源
//这可能意味着它加载了一个ajax调用或者像一个谷歌广告
返回null;
} else {
var aDOMWindow = contentWindow.top.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
var gBrowser = aDOMWindow.gBrowser;
var aTab = gBrowser._getTabForContentWindow(contentWindow.top); //这是可点击的选项卡xul元素,在firefox窗口的标签栏中找到,aTab.linkedBrowser与浏览器var上面相同//可以风格化选项卡,如aTab.style.backgroundColor ='blue'; //可以将选项卡风格化为aTab.style.fontColor ='red';
var browser = aTab.linkedBrowser; //这是选项卡中的浏览器//这是前一节中的示例结束的位置
return {
aDOMWindow:aDWindWindow,
gBrowser:gBrowser,
aTab:aTab ,
browser:browser,
contentWindow:contentWindow
};


// end loadContext stuff

code


$ b 注意:现在先试试这个,我还没有测试,如果你在尝试重定向的时候遇到安全错误,那么创建一个chrome.manifest文件并把它放在根目录下。如果它抛出一个安全错误,你肯定需要一个chrome.manifest文件,这将毫无疑问地修复它。我会在今晚晚些时候测试一下,当我得到一些时间。

chrome.manifest应该是这样的:

 内容kaboom-data ./resources/kaboom/data/ contentaccessible = yes 

然后在上面的代码方式中,改变来自 goodies.contentWindow.location = self.data.url('pages / test.html'); to goodies.contentWindow.location ='chrome://kaboom-data/pages/test.html');


I am creating a firefox addon using the SDK. My goal is simple, to intercept a specific iframe and load my own HTML page (packaged as a resource with my addon) instead of the content that was requested originally.

So far I have the following code:

var httpRequestObserver =
{
    observe: function(subject, topic, data)
    {
        var httpChannel, requestURL;

        if (topic == "http-on-modify-request") {
            httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
            requestURL = httpChannel.URI.spec;

            var newRequestURL, i;

            if (/someurl/.test(requestURL)) {
                var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);

                httpChannel.redirectTo(ioService.newURI(self.data.url('pages/test.html'), undefined, undefined));
            }

            return;
        }
    }
};

var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
observerService.addObserver(httpRequestObserver, "http-on-modify-request", false);

This code works in that it detects the proper iframe loading and does the redirect correctly. However, I get the following error:

How can I get around this limitation?

解决方案

actually man i was really over thinking this.

its already solved when I changed to using loadContext. Now when you get loadContext you get the contentWindow of whatever browser element (tab browser, or frame or iframe) and then just abort the http request like you are doing and then loadContext.associatedWindow.document.location = self.data('pages/tests.html');

done

ill paste the code here removing all the private stuff. you might need the chrome.manifest ill test it out and paste the code back here

Cu.import('resource://gre/modules/Services.jsm');

var httpRequestObserver = {
    observe: function (subject, topic, data) {
        var httpChannel, requestURL;

        if (topic == "http-on-modify-request") {
            httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
            requestURL = httpChannel.URI.spec;

            var newRequestURL, i;

            if (/someurl/.test(requestURL)) {
                var goodies = loadContextGoodies(httpChannel);
                if (goodies) {
                    httpChannel.cancel(Cr.NS_BINDING_ABORTED);
                    goodies.contentWindow.location = self.data.url('pages/test.html');
                } else {
                    //dont do anything as there is no contentWindow associated with the httpChannel, liekly a google ad is loading or some ajax call or something, so this is not an error
                }
            }

            return;
        }
    }
};
Services.obs.addObserver(httpRequestObserver, "http-on-modify-request", false);





//this function gets the contentWindow and other good stuff from loadContext of httpChannel
function loadContextGoodies(httpChannel) {
    //httpChannel must be the subject of http-on-modify-request QI'ed to nsiHTTPChannel as is done on line 8 "httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);"
    //start loadContext stuff
    var loadContext;
    try {
        var interfaceRequestor = httpChannel.notificationCallbacks.QueryInterface(Ci.nsIInterfaceRequestor);
        //var DOMWindow = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow); //not to be done anymore because: https://developer.mozilla.org/en-US/docs/Updating_extensions_for_Firefox_3.5#Getting_a_load_context_from_a_request //instead do the loadContext stuff below
        try {
            loadContext = interfaceRequestor.getInterface(Ci.nsILoadContext);
        } catch (ex) {
            try {
                loadContext = subject.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext);
            } catch (ex2) {}
        }
    } catch (ex0) {}

    if (!loadContext) {
        //no load context so dont do anything although you can run this, which is your old code
        //this probably means that its loading an ajax call or like a google ad thing
        return null;
    } else {
        var contentWindow = loadContext.associatedWindow;
        if (!contentWindow) {
            //this channel does not have a window, its probably loading a resource
            //this probably means that its loading an ajax call or like a google ad thing
            return null;
        } else {
            var aDOMWindow = contentWindow.top.QueryInterface(Ci.nsIInterfaceRequestor)
                .getInterface(Ci.nsIWebNavigation)
                .QueryInterface(Ci.nsIDocShellTreeItem)
                .rootTreeItem
                .QueryInterface(Ci.nsIInterfaceRequestor)
                .getInterface(Ci.nsIDOMWindow);
            var gBrowser = aDOMWindow.gBrowser;
            var aTab = gBrowser._getTabForContentWindow(contentWindow.top); //this is the clickable tab xul element, the one found in the tab strip of the firefox window, aTab.linkedBrowser is same as browser var above //can stylize tab like aTab.style.backgroundColor = 'blue'; //can stylize the tab like aTab.style.fontColor = 'red';
            var browser = aTab.linkedBrowser; //this is the browser within the tab //this is where the example in the previous section ends
            return {
                aDOMWindow: aDOMWindow,
                gBrowser: gBrowser,
                aTab: aTab,
                browser: browser,
                contentWindow: contentWindow
            };
        }
    }
    //end loadContext stuff
}

NOTE: Now try this first, I didn't test it yet, if you get a security error when it tries to redirect then create a chrome.manifest file and put it in the root directory. If it throws a security error than you definitely need a chrome.manifest file and that will without question fix it up. I'll test this myself later tonight when I get some time.

The chrome.manifest should look like this:

content kaboom-data ./resources/kaboom/data/ contentaccessible=yes

Then in the code way above change the redirect line from goodies.contentWindow.location = self.data.url('pages/test.html'); to goodies.contentWindow.location = 'chrome://kaboom-data/pages/test.html');.

这篇关于尝试从Firefox插件(SDK)中的资源加载内容时出现安全性错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-01 17:15