私はFirefox&Chrome=のUserScript拡張機能を作成していますが、ウェブサイトのJavaScriptでいくつかのコードを使用しようとしています。たとえば:
_function: myFunction(){
return Grooveshark.playNextSong();
}
_
問題は、このコードをテストすると、Grooveshark
がnull参照になることです。
私はそれを行った他の人々がいることを知っています:
しかし、なぜ私の単純な拡張機能がGroovesharkのJavaScript関数を呼び出せないのかはわかりません。
これを機能させるには、スクリプトをドキュメントに「追加」する必要がありますか?:document.document.body.appendChild(script);
Greasemonkeyは拡張機能のJavaScriptをすでに挿入していませんか?誰かがこれを明確にしてくれませんか?.
ありがとう。
Greasemonkeyは拡張機能のJavaScriptを既に挿入していませんか?誰かがこれを明確にしてくれませんか?.
Greasemonkeyは sandbox でスクリプトを実行します。これは、ページ内のJavaScriptに直接アクセスしない制限された環境です。以前のバージョンのGreasemonkeyはスクリプトをページに直接挿入していましたが、これにより深刻なセキュリティの脆弱性が生じました。古いモデルでは、スクリプトはブラウザークロムの昇格された権限で実行されていました。これにより、リモートページが 巧妙なJavaScript を使用してGreasemonkeyの組み込み関数にアクセスできるようになりました。これは悪かった:
通常のxmlttprequestオブジェクトとは異なり、Greasemonkeyスクリプトには独自のGM_xmlhttprequestオブジェクトが含まれており、通常はxmlhttprequestに適用される同じOriginポリシーに関係なく、コンピューターのローカルファイルにアクセスしたり、任意のサイトに任意のリクエストを送信したりできます。 (ソース)
今日、Greasemonkeyスクリプトからwindow
オブジェクトにアクセスすると、実際の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);
GreaseMonkeyスクリプト(およびChromeのユーザースクリプト)で宣言された関数と変数は、明らかな理由により、Webページで宣言されたものとは別に保持されます。 GM Firefoxのスクリプトの場合、 unsafeWindow
を使用してグローバル変数にアクセスできます。
安全性と互換性のための最良のアプローチは、スクリプト要素を使用してページに関数を挿入することです。ユーザースクリプトで次のスニペットを使用しています。
function addFunction(func, exec) {
var script = document.createElement("script");
script.textContent = "-" + func + (exec ? "()" : "");
document.body.appendChild(script);
}
"-"
ここでは、関数が式として解析されることを確認しているため、exec
を使用すると、関数を追加するとすぐに実行できます。次のように関数を呼び出します。
function myFunction () {
return Grooveshark.playNextSong();
}
// Inject the function and execute it:
addFunction(myFunction, true);