我想创建一个重写某些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-无处不在的插件,但那里的代码相当复杂,感觉应该有一种更简单的方法来实现它。
答案 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);