36

Firefox と Chrome 用の UserScript 拡張機能を作成しており、Web サイトの JavaScript でコードの一部を使用しようとしています。

function: myFunction(){
    return  Grooveshark.playNextSong();
}

問題は、このコードをテストする Groovesharkと、null 参照になることです。

私はそれをやった他の人がいることを知っています:

BetterGrooveshark を参照

しかし、私の単純な拡張機能が Grooveshark の JavaScript 関数を呼び出せない理由がわかりません。

これを機能させるには、スクリプトをドキュメントに「追加」する必要がありますか?: document.document.body.appendChild(script);

Greasemonkey は既に私の拡張機能 JavaScript を挿入していませんか? 誰かが私のためにこれを明確にしてください。

ありがとう。

4

2 に答える 2

77

バックグラウンド

Greasemonkey は私の拡張機能 JavaScript を既に挿入していませんか? 誰かが私のためにこれを明確にしてください。

Greasemonkey は、ページ内の JavaScript に直接アクセスできない制限された環境であるサンドボックスでスクリプトを実行します。Greasemonkey の以前のバージョンでは、スクリプトをページに直接挿入していましたが、これにより深刻なセキュリティ上の脆弱性が生じていました。古いモデルでは、スクリプトはブラウザ クロームの昇格された権限で実行され、リモート ページは巧妙な JavaScriptを使用して Greasemonkey の組み込み関数にアクセスできました。これは悪かった:

Greasemonkey スクリプトには独自の GM_xmlhttprequest オブジェクトが含まれており、通常の xmlttprequest オブジェクトとは異なり、通常 xmlhttprequest に適用される同一オリジン ポリシーに関係なく、コンピュータの任意のローカル ファイルにアクセスしたり、任意のサイトに任意のリクエストを作成したりできます。(ソース)

window現在、Greasemonkey スクリプトからオブジェクトにアクセスすると、実際の のプロパティを間接的に参照するラッパー オブジェクトが得られます。windowこのラッパー オブジェクトは安全に変更できますが、重要な制限があります。実際のウィンドウ オブジェクトへのアクセスはunsafeWindow(の省略形window.wrappedJSObject) によって提供されます。を使用するとunsafeWindow、Greasemonkey の元のセキュリティ問題がすべて再び発生し、Chrome では利用できません。可能な限り避けるべきです。

幸いなことに、Greasemonkey の新しいセキュリティ モデルを安全に使用するには、少なくとも 2 つの方法があります。

スクリプト インジェクション

Greasemonkey スクリプトが DOM に安全にアクセスできるようになったので、ターゲット ドキュメントの にタグを挿入するのは簡単です。<script><head>次のような関数を作成します。

function exec(fn) {
    var script = document.createElement('script');
    script.setAttribute("type", "application/javascript");
    script.textContent = '(' + fn + ')();';
    document.body.appendChild(script); // run the script
    document.body.removeChild(script); // clean up
}

使い方は簡単です:

exec(function() {
    return Grooveshark.playNextSong();
});

ロケーションハック

スクリプト インジェクションは場合によってはやり過ぎかもしれません。特に、必要なのはページ内の変数の値を変更するか、単一の関数を実行することだけである場合です。Location Hackは、javascript:URL を利用してドキュメントのコンテンツ内のコードにアクセスします。これは、Greasemonkey スクリプト内からブックマークレットを実行するのとよく似ています。

location.assign("javascript:Grooveshark.playNextSong();void(0)");

ボーナススクリプト

上記の例を示す完全な Greasemonkey スクリプトを次に示します。このページで実行できます。

// ==UserScript==
// @name           Content Function Test
// @namespace      lwburk
// @include        http://stackoverflow.com/questions/5006460/userscripts-greasemonkey-calling-a-websites-javascript-functions
// ==/UserScript==

function exec(fn) {
    var script = document.createElement('script');
    script.setAttribute("type", "application/javascript");
    script.textContent = '(' + fn + ')();';
    document.body.appendChild(script); // run the script
    document.body.removeChild(script); // clean up
}

window.addEventListener("load", function() {
    // script injection
    exec(function() {
        // alerts true if you're registered with Stack Overflow
        alert('registered? ' + isRegistered);
    });
    // location hack
    location.assign("javascript:alert('registered? ' + isRegistered);void(0)");
}, false);
于 2011-02-15T17:11:26.057 に答える
11

GreaseMonkey スクリプト (および Chrome のユーザー スクリプト) で宣言された関数と変数は、明らかな理由から、Web ページで宣言されたものとは別に保持されます。Firefox の GM スクリプトの場合、 経由でグローバル変数にアクセスできますunsafeWindow

安全性と互換性を確保するための最善の方法は、スクリプト要素を使用して関数をページに挿入することです。ユーザー スクリプトで次のスニペットを使用します。

function addFunction(func, exec) {
  var script = document.createElement("script");
  script.textContent = "-" + func + (exec ? "()" : "");
  document.body.appendChild(script);
}

hereは"-"、関数が式として解析されることをexec確認するため、追加時にすぐに実行するために使用できます。次のように関数を呼び出します。

function myFunction () {
    return Grooveshark.playNextSong();
}

// Inject the function and execute it:
addFunction(myFunction, true);
于 2011-02-15T16:42:18.163 に答える