从Firefox插件中重写的选择性URL?

时间:2011-09-28 23:59:33

标签: javascript firefox-addon

我想创建一个重写某些URL的Firefox插件。例如,如果页面尝试加载文件http://my.com/foo.js,我想重写URL以便从http://my-other.org/bar.js加载。而且我不希望它看起来像302重定向,因为请求可能源自XHR调用,并且我不希望浏览器因为它是跨域而拒绝重定向请求。 / p>

我查看了TamperData和HttpFox源代码,以了解如何解决这个问题。我已经尝试创建一个侦听http-on-modify-request的观察者,并且在侦听器中尝试重写URL。问题是nsiHttpChannel对象似乎让我做了几乎所有事情 - 覆盖标题,取消请求,捕获响应等 - 除了覆盖URL。简单地更改nsiHttpChannel的originalURI和URI属性的内容似乎也不起作用。

我能找到的唯一有希望的指针是HTTPS-无处不在的插件,但那里的代码相当复杂,感觉应该有一种更简单的方法来实现它。

2 个答案:

答案 0 :(得分:1)

我们可以使用新的覆盖nsiHttpChannel来执行此操作,这样做有点复杂但幸运的是,加载项https-everywhere实现此操作以强制执行https连接。

https-everywhere的源代码可用here

这需要的大部分代码都在文件中

IO Util.js ChannelReplacement.js(不再在源代码树中)

我们可以单独使用上述文件,前提是我们已经设置了基本变量,如Cc,Ci设置和函数xpcom_generateQI

var httpRequestObserver =
{ 
  observe: function(subject, topic, data) {
    if (topic == "http-on-modify-request") {

        var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);     
        var requestURL = subject.URI.spec;

        if(isToBeReplaced(requestURL))  {

            var newURL = getURL(requestURL);        
             ChannelReplacement.runWhenPending(subject, function() {
                    var cr = new ChannelReplacement(subject, ch);
                    cr.replace(true,null);
                    cr.open();
                });
        }
    }

  },

  get observerService() {
    return Components.classes["@mozilla.org/observer-service;1"]
                     .getService(Components.interfaces.nsIObserverService);
  },

  register: function() {
    this.observerService.addObserver(this, "http-on-modify-request", false);

  },

  unregister: function() {
    this.observerService.removeObserver(this, "http-on-modify-request");

  }
};


httpRequestObserver.register();

代码将替换请求不重定向。

虽然我已经足够好地测试了上面的代码,但我不确定它的实现。据我所知,它复制了所请求频道的所有属性,并将它们设置为要覆盖的频道。之后以某种方式使用新通道提供原始请求所请求的输出。

P.S。我看过一篇SO帖子,其中提出了这种方法。

答案 1 :(得分:0)

gliptak的回答是正确的,但现在已经过时了。

我写了一个非常简单的Firefox插件,可以完成您所描述的内容。您可以使用其来源作为参考。

// intercept and occasionally modify HTTP/HTTPS requests...
let httpObserver = {
    observe: function (aSubject, aTopic, aData) {
        aSubject.QueryInterface(Ci.nsIHttpChannel);
        let url = aSubject.URI.spec;
        let modUrl = modifyUrlIfNeeded(url);
        if (modUrl){
            // replace URL and referrer in request...
            let urlObj = ioService.newURI(modUrl, aSubject.URI.originCharset, null);
            aSubject.redirectTo(urlObj);
        }
    }
};
observerService.addObserver(httpObserver, "http-on-modify-request", false);

https://github.com/tristanisme/gahmm/blob/master/index.js