1

例を読むと、これは非常に簡単なはずです。これが私のコードです:

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);

ここで、testfoo.jsには次のものが含まれます。

window.rhk_test1 = 'testval1';
rhk_test2 = 'testval2';
var rhk_test3 = 'testval3';

window.alert('Running testfoo.js');

「Runningtestfoo.js」というアラートが表示されるので、ファイルが見つかり、実行されます。また、wndが「オブジェクト」であることに注意するアラートを受け取ります(予想どおり、他の場所で初期化されています)。ただし、他のすべてのアラートは、さまざまなtypeof()呼び出しに対して「未定義」を示します。当然、これらすべてに価値があるとは思いませんが、少なくともそのうちの1つが何かを示すことを期待していました。

私の価値観はどうなりましたか?それらはwndのプロパティにあるはずではありませんか?

私はWindows7でFirefox19.0を実行しています(それが重要な場合)。

4

2 に答える 2

3

それは実際には少し複雑で、何であるかに依存し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は、添え字の最上位にあるようにアクセスできます。

于 2013-03-03T22:25:46.520 に答える
1

注: より一般的な概要については、Wladimir Palant の回答を参照してください。

私の例の場合、多かれ少なかれ妥当な期待を持って、実際に関数を正しく使用していました。この問題は、Firefox の XPCNativeWrapper 機能が原因でした。

私はまだ詳細を理解するのに苦労していますが、一言で言えば、私のwndオブジェクトは XPCNativeWrapper でラップされてtestfoo.jsいて、「保護された」スクリプトと見なされていました。からtestfoo.js

解決策は、次のように、オブジェクトを添字に渡す前 (または後 -- これも機能します) にラップを解除することです。

var wnd = XPCNativeWrapper.unwrap(doc.defaultView);

それを行うとすぐに、によって変更された変数/プロパティtestfoo.jsが親スクリプトに表示されるようになりました。

これが「安全」かどうかを判断できるほど、完全なインフラストラクチャをまだ十分に理解していません。結局のところ、これはブラウザー ページ上の悪意のあるコードから拡張機能を保護するために設計されたセキュリティ メカニズムです。

また、添え字で定義されたメソッドにオブジェクトを渡す際に問題が発生しています (私の例には示されていません)。そのために、別の質問をします。

簡単に言うと、アンラップは、私の質問で提起された差し迫った問題の(おそらく「その」)解決策ですが、そもそも質問を引き起こした問題の完全な解決策ではないようです。

于 2013-03-06T19:47:24.427 に答える