【问题标题】:What is missing in my nsIContentPolicy Firefox/IceWeasel extension XPCOMponent implementation for the shouldLoad to be called?我的 nsIContentPolicy Firefox/IceWeasel 扩展 XPCOMponent 实现中缺少什么来调用 shouldLoad?
【发布时间】:2012-02-03 05:06:13
【问题描述】:

总之

为什么,根据下面详述的代码,shouldLoad 函数没有被调用?

加长版

我的目标

我正在尝试构建一个将取消/重定向某些 url 请求的 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 会给出以下结果:

... @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 组件,@abc.def.com/policycomp;1 content-policy,@mozilla.org/no-data-protocol-content-policy;1,@mozilla.org/no-data-protocol-content-policy;1 ...

所以看起来该组件至少有一些正确的地方。 但是,我仍然可以访问 url 中带有“abc”的网页(这让人相信 shouldLoad 函数没有被调用)。

更多信息

我没有在 chrome.manifest 文件中添加任何关于扩展的内容。我相信在 FF/IW 的 3.5.x 版本中我不需要这样做。

问题

  1. 怎么了? :)

  2. 我需要向 chrome.manifest 添加一些内容吗?还是只适用于 FF 4+?

  3. 我是否需要以某种方式进一步实例化组件/服务?比如 onLoad 钩子中的 overlay.js?

  4. 我是否需要以更明确的方式将组件注册为对扩展有效,如果需要,如何?

提前致谢!

【问题讨论】:

  • 您实际上是在使用 Firefox 3.5(不管名字)?使用不久前生命终结的浏览器听起来是个非常糟糕的主意。
  • 这是因为我使用的是非常稳定的 Debian 版本(现在不记得名字了),所以它有一个旧的和过时的(但稳定的!)版本的 FF。 (在 Iceweasel 的化身中)。嗯,我认为这就是原因。也许我可以升级它......嗯......老实说,自从我通常运行 Chrome 以来,我并没有考虑太多,但现在我正在为 FF 开发,我在我的默认平台上使用了 closes 的东西。

标签: firefox xpcom


【解决方案1】:

看起来您没有验证您的 shouldLoad 方法确实没有被调用。我建议使用dump() function 来查看您的组件中真正发生了什么。似乎更有可能正在调用它,但它会引发“aContext.loadURI 不是函数”之类的异常。原因是用于TYPE_DOCUMENT 调用的aContext 是一个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 钩子中的 overlay.js?

不,这是由内置内容策略组件自动发生的。

我是否需要以更明确的方式将组件注册为对扩展有效,如果需要,如何?

不明白你的意思。

【讨论】:

  • 有趣的想法!我一定会尝试并回来。
  • 您的反馈确实是对正确方向的提示。使用转储我可以看到该函数确实被调用了。看来问题是我错过了组件变量名称的大写。 :P 所以我调用了一个未定义的变量来在两个地方获取比较常量(Ci.nsIContentPolicy.TYPE_DOCUMENT 等)。使用正确的 var 名称可以工作。很抱歉在其背后发布了如此微不足道的错误。然而,即使在 TYPE_DOCUMENT 的情况下,它似乎也可以在 aContext 上调用 loadURI。在我继续开发的过程中,我会考虑您的建议。
猜你喜欢
  • 1970-01-01
  • 2019-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多