为什么,基于下面详述的代码,未调用的是shouldLoad函数?
我正在尝试构建一个Firefox / Iceweasel扩展,它将取消/重定向某些网址请求。
基于我在网上看到的,一种方法(如果我想拦截每个请求而不仅仅是顶层文档)这样做是为了创建一个实现nsIContentPolicy接口的XPCOM组件,并注册该组件扩展名,并使用shouldLoad函数检查请求的URL并在适当的时候拒绝。
我已尽最大努力实施了一个组件,并将其与我的扩展程序集成在一起。该组件似乎在compreg.dat等中注册的意义上工作,但是,就我所知,shouldLoad函数不会被调用。
我正在使用与FireFox 3.5.16相对应的IceWeasel版本在Debian Linux上进行开发。
延期我的扩展程序基于给出的示例扩展名 http://kb.mozillazine.org/Getting_started_with_extension_development#reg-em 从本质上讲,它所做的只是添加一个菜单项,打开一个类似警报的对话框,说明你好世界。它有一个onLoad注册,触发并提示“onLoad Reporting!”。警报每次都会毫无问题地触发。
参考我已经安装了扩展重定向器,看似按照相同的原则运行, https://addons.mozilla.org/en-US/firefox/addon/redirector/ 并且它有效(因此我的代码可能是错误,而不是环境恶劣)。
零件我的组件实施基于我在互联网上找到的各种来源。 我把它放在目录{pathtoextension} /helloworld/components/PolicyComponent.js中的一个文件中,其代码如下:
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
const CI = Components.interfaces, CC = Components.classes, CR = Components.results;
var componentobj = null;
function PolicyComponent()
{
// this.wrappedJSObject = this;
}
PolicyComponent.prototype = {
classDescription: "My QWERTY nsIContentPolicy XPCOM Component",
classID: Components.ID("{6ffd2f60-3784-11e1-b86c-0800200c9a66}"),
contractID: "@abc.def.com/policycomp;1",
QueryInterface: XPCOMUtils.generateQI([CI.nsIContentPolicy]),
testFunction: function() { return "Your component is not entirely broken!"; },
_xpcom_categories: [{
category: "content-policy"
}],
_xpcom_factory :
{
createInstance: function(outer, iid)
{
if (outer)
{ throw CR.NS_ERROR_NO_AGGREGATION;}
if (componentobj == null)
{
componentobj = new PolicyComponent();
}
else {}
return componentobj.QueryInterface(iid);
}
},
shouldLoad: function(contentType, contentLocation, requestOrigin, aContext, mimeTypeGuess, extra)
{
if (contentType != Ci.nsIContentPolicy.TYPE_DOCUMENT) {
return Ci.nsIContentPolicy.ACCEPT;
}
if(-1 != contentLocation.spec.search("abc"))
{
aContext.loadURI("http://www.stroustrup.com/", requestOrigin, null);
return Ci.nsIContentPolicy.REJECT_REQUEST;
}
return CI.nsIContentPolicy.ACCEPT;
},
shouldProcess: function(contentType, contentLocation, requestOrigin, insecNode, mimeType, extra) {
return CI.nsIContentPolicy.ACCEPT;
}
};
var components = [PolicyComponent];
if (XPCOMUtils.generateNSGetFactory)
var NSGetFactory = XPCOMUtils.generateNSGetFactory([PolicyComponent]);
else
var NSGetModule = XPCOMUtils.generateNSGetModule([PolicyComponent]);
状态
该组件似乎被IceWeasel认可。如果我删除compreg.dat和xpti.dat并重新启动IceWeasel,compreg.dat中的grep on content-policy会给出以下结果:
... @mozilla.org/embedding/browser/content-policy;1,{f66bc334-1dd1-11b2-bab2-90e04fe15c19} content-policy,@mozilla.org/data-document-content-policy;1,@mozilla.org/data-document-content-policy;1 content-policy,My QWERTY nsIContentPolicy XPCOM Component,@abc.def.com/policycomp;1 content-policy,@mozilla.org/no-data-protocol-content-policy;1,@mozilla.org/no-data-protocol-content-policy;1 ...
所以看起来组件至少有一些正确的东西。 但是,我仍然可以在网址中使用“abc”访问网页(这使得相信不会调用shouldLoad函数)。
更多信息我没有添加任何有关chrome.manifest文件扩展名的内容。我相信我不需要在FF / IW版本3.5.x中这样做。
怎么了? :)
我需要在chrome.manifest中添加一些内容吗?或者仅适用于FF 4 +?
我是否需要以某种方式进一步实例化组件/服务?比如说onLoad hook中的overlay.js?
我是否需要以更明确的方式将组件注册为对扩展有效,如果是,如何?
提前致谢!
答案 0 :(得分:1)
看起来您没有确认您的shouldLoad
方法确实没有被调用。我建议使用dump() function来查看组件中发生的事情。它似乎更有可能被调用,但它抛出一个异常,如“aContext.loadURI不是一个函数”。原因是aContext
次调用的TYPE_DOCUMENT
是一个HTMLDocument
对象,并且没有loadURI
方法。您可能想要拨打aContext.defaultView.location.replace()
。但是,从内容策略执行此操作将是一个安全漏洞(事实上,从内容策略中执行任何可能导致网页脚本运行将是一个安全漏洞)。如果您查看interface definition,您会看到附带大警告。
所以像这样的操作需要延迟发生,以确保在引擎处于一致状态时发生。例如。你可以这样做:
aContext.defaultView.setTimeout("window.location.replace('http://www.stroustrup.com/')", 0);
怎么了? :)
除了我上面提到的,您可能不应该定义自定义_xpcom_factory
功能。内容策略始终用作服务,这意味着它们是自动单例。访问该组件的您自己的代码当然也应该使用getService()
。
我需要在chrome.manifest中添加一些内容吗?或者仅适用于FF 4 +?
是的,对于FF4 +。类似的东西:
component {6ffd2f60-3784-11e1-b86c-0800200c9a66} components/PolicyComponent.js
contract @abc.def.com/policycomp;1 {6ffd2f60-3784-11e1-b86c-0800200c9a66}
category content-policy @abc.def.com/policycomp;1 @abc.def.com/policycomp;1
我是否需要以某种方式进一步实例化组件/服务?比如说onLoad hook中的overlay.js?
不,这是由内置内容策略组件自动发生的。
我是否需要以更明确的方式将组件注册为对扩展有效,如果是,请如何?
不知道你的意思。