如何使用“targetObj"”参数loadSubScript()在firefox扩展

How do I use the "targetObj" parameter to loadSubScript() in firefox extensions?

本文关键字:loadSubScript 扩展 firefox 参数 何使用 targetObj quot      更新时间:2023-09-26

从阅读示例来看,这似乎应该很容易。下面是我的代码:

rhkTest = {
  onPageLoad: function(event) {
    var doc = event.originalTarget;
    var wnd = doc.defaultView;
    var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
      .getService(Components.interfaces.mozIJSSubScriptLoader);
    loader.loadSubScript("chrome://rhkoshi-extension/content/testfoo.js", wnd);
    alert('typeof(wnd) = ' + typeof(wnd));
    alert('typeof(wnd.window.rhk_test1) = ' + typeof(wnd.window.rhk_test1));
    alert('typeof(wnd.window.rhk_test2) = ' + typeof(wnd.window.rhk_test2));
    alert('typeof(wnd.window.rhk_test3) = ' + typeof(wnd.window.rhk_test3));
    alert('typeof(wnd.rhk_test1) = ' + typeof(wnd.rhk_test1));
    alert('typeof(wnd.rhk_test2) = ' + typeof(wnd.rhk_test2));
    alert('typeof(wnd.rhk_test3) = ' + typeof(wnd.rhk_test3));
    alert('typeof(rhk_test1) = ' + typeof(rhk_test1));
    alert('typeof(rhk_test2) = ' + typeof(rhk_test2));
    alert('typeof(rhk_test3) = ' + typeof(rhk_test3));
    alert('typeof(this.rhk_test1) = ' + typeof(this.rhk_test1));
    alert('typeof(this.rhk_test2) = ' + typeof(this.rhk_test2));
    alert('typeof(this.rhk_test3) = ' + typeof(this.rhk_test3));
    alert('typeof(window.rhk_test1) = ' + typeof(window.rhk_test1));
    alert('typeof(window.rhk_test2) = ' + typeof(window.rhk_test2));
    alert('typeof(window.rhk_test3) = ' + typeof(window.rhk_test3));
  },
  onLoad: function(event) {
    var appcontent = document.getElementById("appcontent");
    if (appcontent) {
      appcontent.addEventListener("DOMContentLoaded", rhkTest.onPageLoad, true);
    }
  },
};  
window.addEventListener("load", function(e) { rhkTest.onLoad(e); }, false);
window.rhk_test1 = 'testval1';
rhk_test2 = 'testval2';
var rhk_test3 = 'testval3';
window.alert('Running testfoo.js');

我得到警告"Running testfoo.js",所以文件被找到并执行。我还得到一个警告,指出wind是一个"对象"(正如预期的那样——它在其他地方初始化了)。然而,对于各种typeof()调用,所有其他警报都显示"未定义"。当然,我不期望所有的都有值,但我希望至少其中的一个可能显示一些东西。

我的价值观怎么了?他们不是应该在风的属性里吗?

我在Windows 7上运行的是Firefox 19.0。

这实际上有点复杂,取决于wnd是什么。您可以使用常规对象作为下标的作用域:

var myScope = this;
var subscriptScope = {};
loader.loadSubScript("testfoo.js", subscriptScope);

然而,作用域并不是完全隔离的。下面是testfoo.js中的一些代码示例:

var foo = "bar;      // Creates subscriptScope.foo
xyz = 1;             // Creates myScope.xyz
function dummy() {}  // Creates subscriptScope.dummy
var outer = myScope; // Assigns a value from outer scope

因此,当下标的变量和函数在其作用域中定义时,它仍然可以访问加载它的脚本的作用域——未声明的变量仍然会在外部作用域中创建,并且外部作用域中将搜索无法在下标作用域中解析的变量。

如果你真的想隔离下标,那么你应该使用一个"合适的"全局对象,比如窗口对象或沙盒:

var myScope = this;
var subscriptScope = new Components.utils.Sandbox("about:blank");
loader.loadSubScript("testfoo.js", subscriptScope);

现在testfoo.js将无法再访问外部作用域:

var foo = "bar;      // Creates subscriptScope.foo
xyz = 1;             // Creates subscriptScope.xyz
function dummy() {}  // Creates subscriptScope.dummy
var outer = myScope; // Exception: myScope is not defined

请注意,window变量没有什么特别之处—如果您希望下标具有该变量,则必须在作用域对象中定义它,例如:

subscriptScope.window = subscriptScope;

作用域对象本身可以作为下标顶层的this访问

注意:参见vladimir Palant的回答获得更一般的概述。

在我的例子中,我实际上正确地使用了这个函数,并有或多或少合理的期望。这个问题是由Firefox的XPCNativeWrapper功能引起的。

我仍然在努力理解细节,但简而言之,我的wnd对象被包装在XPCNativeWrapper中,testfoo.js被认为是一个"受保护的"脚本,这意味着一旦控制从testfoo.js传递回来,我就看不到对对象所做的任何更改。

解决方案是在将对象传递给下标之前(或之后——也可以)展开对象,如下所示:
var wnd = XPCNativeWrapper.unwrap(doc.defaultView);

当我这样做的时候,被testfoo.js修改的变量/属性对父脚本是可见的。

我还不了解完整的基础设施,不知道这是否"安全"。毕竟,这是一种安全机制,旨在保护我的扩展免受浏览器页面上恶意代码的攻击。

我还发现了将对象传递到下标定义的方法中的一些问题(在我的示例中没有显示)。对此,我将单独提一个问题。

长话短说:对于我的问题中提出的直接问题,展开是一种(可能是"唯一的")解决方案,但似乎并不能完全解决我所遇到的困难,这些困难首先产生了这个问题。