Firefox SDK:如何使某个域名触发 [英] Firefox SDK: How to make trigger for certain domain
问题描述
我需要在网址 *。net 上的网站上发送请求,并采取一些措施(停止请求并从磁盘放置HTML代码,但是我可以这么做)。我如何理解这些要求?
我尝试使用进度监听器,但有些地方是错误的:
const STATE_START = Ci.nsIWebProgressListener.STATE_START;
pre>
var myListener = {
QueryInterface:XPCOMUtils.generateQI([nsIWebProgressListener,
nsISupportsWeakReference]),
onStateChange:function(aWebProgress ,aRequest,aFlag,aStatus){
if(aFlag& STATE_START){
//动作
}
}
解决方案使用nsIHTTPChannel和observer服务。复制粘贴它。然而.net可以包含在资源中,比如javascript的东西,如果你想测试它是否特定的一个窗口,你必须检查LOAD_INITIAL_DOCUMENT_URI的一些加载标志,也要检查
Cu.import( '资源://gre/modules/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(httpChannel.loadFlags& httpChannel.LOAD_INITIAL_DOCUMENT_URI){
// ok继续,因为loadFlags是文档
} else {
//它不是文档,可能是资源像一个JS文件图像或CSS的东西,但也许可能是ajax调用
返回;
if(requestURL.indexOf('.net')){
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);上完成的http-on-modify-request的主题。
//启动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';
if(aTab == null){
return null;
}
else {
var browser = aTab.linkedBrowser; //这是选项卡中的浏览器//这是前一节中的示例结束的位置
return {
aDOMWindow:aDOMWindow,
gBrowser:gBrowser,
aTab:aTab ,
browser:browser,
contentWindow:contentWindow
};
// end loadContext stuff
code $ preI need to catch requests on sites with URLs *.net and take some actions (stop request and put HTML code from disk, but this I can do). How do I catch these requests?
I tried to use progress listeners, but something is wrong:
const STATE_START = Ci.nsIWebProgressListener.STATE_START; var myListener = { QueryInterface: XPCOMUtils.generateQI(["nsIWebProgressListener", "nsISupportsWeakReference"]), onStateChange: function(aWebProgress, aRequest, aFlag, aStatus) { if (aFlag & STATE_START) { // actions } }
解决方案use nsIHTTPChannel and observer service. copy paste it. however .net can be included in resources like javascript things, if you want to test if its specfically a window you have to check for some load flags of LOAD_INITIAL_DOCUMENT_URI, also will want to chec
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 (httpChannel.loadFlags & httpChannel.LOAD_INITIAL_DOCUMENT_URI) { //ok continue because loadFlags is a document } else { //its not a document, probably a resource like a js file image or css or something, but maybe could be ajax call return; } if (requestURL.indexOf('.net')) { 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'; if (aTab == null) { return null; } else { 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 }
这篇关于Firefox SDK:如何使某个域名触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!