我已经尝试了很长一段时间,但都没有好的结果。
var myObserver = {
observe: function(subject, topic, data)
{
if (topic == "http-on-examine-response")
{
// implement later
}
else if(topic == "http-on-modify-request")
{
// implement later
}
},
QueryInterface : function (id)
{
if (id.equals(Components.interfaces["nsIObserver"]) ||
id.equals(Components.interfaces["nsISupports"]))
{
return this;
}
throw Components.results.NS_NOINTERFACE;
}
};
var obs = new Service("observer-service", "ObserverService");
obs.addObserver(myObserver, "http-on-modify-request", false);基本上,在http-on-modify-request上,我知道如何检查URI,找出它与哪个窗口(如果有的话)相关联,以及一大堆其他东西。我不明白的是如何重定向请求,我知道这是可能的,因为我可以在发出任何请求之前获得一个nsIHttpChannel。
有人知道该怎么办吗?:/我断断续续地试了几个星期,但一无所获。
发布于 2012-09-26 20:43:24
我们可以通过用新的nsiHttpChannel覆盖https来实现这一点,这样做有点复杂,但幸运的是,附加组件https-everywhere实现了这一点,以强制https连接。
https-everywhere的源代码可以在here上找到
执行此操作所需的大部分代码都在文件中
IO Util.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();该代码将替换的请求不重定向。
虽然我已经很好地测试了上面的代码,但我不确定它的实现。据我所知,它复制请求通道的所有属性,并将它们设置为要覆盖的通道。之后,使用新信道以某种方式提供原始请求所请求的输出。
附言:我看过一篇关于这个方法的帖子。
发布于 2012-05-26 09:13:29
我的印象是,你不能在这个级别做这件事--我尝试了各种方法,从外部“欺骗”需要创建nsIHttpChannel的代码(示例在post结束时)。
我建议的是,如果你想要重定向,联系频道的所有者窗口( 99%的时间都可以工作),并指示它重定向。我知道它的行为是不一样的,但是因为我不知道你为什么要这么做,所以在外部(对用户来说)它看起来和你所要求的做的是一样的。
以下是我所尝试的基本内容:
if(aTopic == "http-on-examine-response") {
var request = aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
if(!request.URI.spec.match("^http://www.apple.com/")) {
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var ch = ios.newChannel("http://www.apple.com/", null, null);
var listener = {
QueryInterface : XPCOMUtils.generateQI([Ci.nsIChannelEventSink]),
onDataAvailable: function() {},
onStopRequest: function() {},
onStartRequest: function() {}
};
ch.asyncOpen(listener,null);
var eventSink = request.notificationCallbacks.getInterface(Ci.nsIChannelEventSink);
eventSink.asyncOnChannelRedirect(request,ch,Ci.nsIChannelEventSink.REDIRECT_INTERNAL,function() {});
} 发布于 2013-11-27 17:47:39
我是这样做的:在"http-on-modify-request"事件上停止nsIHttpChannel,获取当前窗口的浏览器对象,调用browser.loadURI。
var utils = require("sdk/window/utils");
function needsRedirect(url) {
// to be implemented
return true;
}
function generateNewUrl(url) {
// to be implemented
return "http://www.example.com/";
}
Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService)
.addObserver({
observe: function(subject, topic, data) {
var channel = subject.QueryInterface(Ci.nsIHttpChannel);
var url = channel.originalURI.spec;
if (needsRedirect(url)) {
//stop
channel.cancel(Cr.NS_BINDING_ABORTED);
//redirect
var gBrowser = utils.getMostRecentBrowserWindow().gBrowser;
var domWin = channel.notificationCallbacks.getInterface(Ci.nsIDOMWindow);
var browser = gBrowser.getBrowserForDocument(domWin.top.document);
browser.loadURI(generateNewUrl(url));
}
}
}, "http-on-modify-request", false);https://stackoverflow.com/questions/2237108
复制相似问题