在Firefox扩展中redirect请求(nsiHttpChannel?)
我已经在这个很长一段时间尝试了,没有好的结果。
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,找出与哪个窗口(如果有)关联,以及其他一些东西。 我无法弄清楚的是如何redirect一个请求,我知道这是可能的,因为在发送请求之前,我可以得到一个nsIHttpChannel。
任何人都知道该怎么办? :/我已经尝试了几个星期的closures,并没有得到任何好处。
我们可以通过用新的覆盖nsiHttpChannel
来做到这一点,这样做有点复杂,但幸运的是,附加的https-everywhere
实现这个强制https连接。
https-everywhere
的源代码在这里可用
大部分所需的代码都在文件中
[ IO Util.js
] [ ChannelReplacement.js
]
我们可以单独使用上面的文件,只要我们有基本的variables如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();
代码将取代不redirect的请求。
虽然我已经很好的testing了上面的代码,但我不确定它的实现。 据我所知,它复制了所请求通道的所有属性,并将它们设置为要覆盖的通道。 之后以某种方式,原始请求所请求的输出将使用新的通道提供。
PS我曾看过一个SOpost,其中提出了这种方法。
我的印象是,你不能在这个层面上做到这一点 – 我尝试了各种各样的外部“欺骗”代码,要求创build一个nsIHttpChannel的方法(例如在post的末尾)。
我会build议如果你想要redirect,请联系频道的所有者窗口(99%的时间),并指示它redirect。 我知道这不会有相同的performance,但是因为我不知道你为什么要这样做,所以这对外部(对用户)似乎和你所要求的一样。
以下是我正在尝试的基础知识:
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() {}); }
我这样做了:在"http-on-modify-request"
事件"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);
在testing某些东西时,我创build了其他答案中提到的通道replace逻辑的精简版本(请参阅此要点 )。
总的想法似乎是将所有关键属性转移到新频道,从旧频道中删除callback,以便操纵不会跳过页面加载,然后closures旧频道。
通过一些修改,可以更改文档加载的页面URI或保持原样。
警告:这只是一个简单的方法来加载几个页面,我没有深入的testing,它可能会打破一些情况。 我怀疑为什么HTTPS Everywhere更复杂。
- Div 100%的高度适用于Firefox,但不适用于IE
- 如何正确无效的在线/离线networking应用程序的HTML5caching清单?
- 在Firefox中没有显示边框,在表格上有border-collapse,位置:相对于tbody,或单元格上的背景颜色
- 为什么所有浏览器的用户代理都以“Mozilla /”开头?
- 在Firefox中远程使用Google Maps V3时,“google未定义”
- Javascript在Firefox上开发的典型原因是什么?
- 你可以在萤火虫hover状态“粘?”
- 如何从Firefox中的select元素中删除箭头
- Chrome和Firefox中的Javascript中报告了隐藏的“脚本错误”