Greasemonkey: で定義された変数にアクセスできません<script>tags on the actual page.</script>

作成日 2017年11月18日  ·  14コメント  ·  ソース: greasemonkey/greasemonkey

Greasemonkey 4のアップデートにより、jQueryを使用する多くのユーザースクリプトが壊れているようです。 以前のバージョンでは、次のコードは<script>タグでjQueryを使用するページで機能していました。

// ==UserScript==
// <strong i="7">@name</strong>        Variable access test
// <strong i="8">@namespace</strong>   example.com
// ==/UserScript==

$.ready(document, function() {
    console.log("Accessed jQuery successfully.")
});

ただし、これは機能しなくなりました。代わりに、従来の$ is not defined取得するだけです。 これは、 <script>タグが読み込まれる前に、Greasemonkeyがユーザースクリプトを実行している可能性があることを示しています。 ただし、 document.readyStateinteractive場合でもスクリプトが実行されるので、これは奇妙なことです。

ただし、確かに、 window.addEventListener('load', ...)後にjQueryにアクセスしてみました。 見よ、以下は別のエラーを示しています。

// ==UserScript==
// <strong i="19">@name</strong>        Variable access test
// <strong i="20">@namespace</strong>   example.com
// ==/UserScript==

window.addEventListener('load', function() {
    console.log("Before accessing jQuery")
    $;
    console.log("Accessed jQuery successfully!")
});

実行もエラーもスローしません。代わりに、 $にアクセスしようとする


jQueryを使用するすべてのページで試してみると、同じ結果が得られるはずです。 @requireを使用しても、この問題の解決策にはなりません。一部のアプリケーションでは、ページと同じjQueryのインスタンスにアクセスする必要があります。 これは、jQuery以外のスクリプトにも影響を与える可能性があります。

duplicate

最も参考になるコメント

私は今(さまざまな構成で)そのアプローチを試しましたが、何をしても許可エラーが発生し続けます。 この時点で面倒なことは本当に価値がありません。

厳しいように聞こえますが、これが邪魔にならないまで、Tampermonkeyの使用を推奨する必要があると思います。 コンテンツスクリプトは、現在の形では、実際にはユーザースクリプトのユースケースにまったく適合していません。

全てのコメント14件

実際にはGreasemonkeyの問題ではなく、Firefoxコンテンツスクリプトの問題です。
https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Content_scripts#Accessing_page_script_objects_from_content_scripts

独自のwindow.wrappedJSObject割り当てるか、Greasemonkeyがすでにラップされたオブジェクトを割り当てているunsafeWindowを使用します。

@Sxderp 「Greasemonkeyの問題ではない」ことについてはわかりません。TampermonkeyとViolentmonkeyの両方が、このケースを問題なく処理します。 それだけでなく、これはどのブログ投稿にも言及されていない重大な変更です。

既存のユーザースクリプトで期待どおりに機能し、他の一般的なユーザースクリプトマネージャーと相互互換性を持たせるために、これを修正する必要がありますか?

また...これは本当に問題を説明していますか? ルックアップが失敗しただけでなく、スクリプトがフリーズするのはなぜですか?

凍結についてはよくわかりません。 あなたのコードをコピーしました、そしてそれは私のためにフリーズしません。

編集:申し訳ありませんが、「フリーズ」コメントを誤解しました。 Greasemonkeyがもう機能しないという意味だと思いました。 Javascriptが宣言エラーの前に使用にヒットしたため、その行で「フリーズ」(実行を停止)します。 それが「致命的」と見なされることはかなり確実です。 のように、コードの実行を継続しません。


Violentmonkeyコードをざっと見てみると、 <script>要素を作成してスクリプトを挿入しているように見えtabs.executeScripts() APIメソッドを使用するのではなく。

もちろん、それを使用することにはそれ自身の欠点もあります。

それで... Firefoxがその行にぶつかると、それはただ静かに実行を停止しますか? エラーメッセージなし? なんて信じられないほど奇妙なことなのでしょう。

いずれにせよ、既存のユーザースクリプトとの互換性を維持することは目標ではありませんか? 結局のところ、これはニッチな機能ではありません。ページ自体のJavaScriptとのインターフェースは非常に一般的なことです。

いずれにせよ、既存のユーザースクリプトとの互換性を維持することは目標ではありませんか?

もちろん。 私たちは完璧ではありません。これは、ボランティアによって作成された無料のオープンソースプロジェクトです。

この時点で、これを改善する方法についての計画がありますが、Mozillaが安全に実行できるようにする機能を実装するのを待っています。 #2549

@arantius少し対立的に外れたかもしれないと思います...ごめんなさい。

ここでは、使いやすさよりもセキュリティを優先するというのは、考え抜かれた決断だと思います。 状況が解決するまで、スクリプト作成者側の回避策として何ができるでしょうか。 私の特定のケースでは、スクリプトの先頭でvar $ = window.wrappedJSObject.$;var $= unsafeWindow.$;両方を試しましたが、 $(document).ready(...)を使おうとすると別のエラーが発生しました: Error: Permission denied to access property Symbol.toStringTag

エラー:プロパティSymbol.toStringTagへのアクセスが許可されていません

これはwindow.wrappedJSObject.$問題ではないと思いますが、オブジェクトリテラルとして、またはnewコンストラクターを使用して、ユーザースクリプトで作成した他のオブジェクトが適切にインポートされていません。アクセスしようとしているスコープ(おそらくページのウィンドウスコープ)。

上記のリンクは、必要なcloneInto詳細を提供します。

いいえ、問題はwindow.wrappedJSObject.$あると確信しています。 以下は、まったく同じエラーで失敗します。

// ==UserScript==
// <strong i="7">@name</strong>        Variable access test
// <strong i="8">@namespace</strong>   example.com
// ==/UserScript==

var $ = window.wrappedJSObject.$;

$(document).ready(function() {});

ただし、これは黙って失敗します。

// ==UserScript==
// <strong i="12">@name</strong>        Variable access test
// <strong i="13">@namespace</strong>   example.com
// ==/UserScript==

var $ = window.wrappedJSObject.$;

$.ready(function() {});

cloneIntoを使用してみましたが、役に立ちません。 $のページのインスタンスを使用する短い例のユーザースクリプトを提供できると思いますか?

ああ、その場合、あなたはその機能にアクセスする許可を持っていません。 次に、 exportFunctionを使用する必要があります。

// ==UserScript==
// <strong i="7">@name</strong>         ExampleJQuery
// <strong i="8">@version</strong>      1
// <strong i="9">@include</strong>      *
// <strong i="10">@grant</strong>        none
// ==/UserScript==

var unsafeWindow = window.wrappedJSObject;
var $;

// For sanity just return if we don't have the object
if (typeof unsafeWindow.$ === 'undefined') {
  console.log('No jQuery object, returning');
  return;
} else {
  $ = unsafeWindow.$;
}

// Create the function we want to export
function onReady() {
  console.log("I'm ready!");
}
// Export it. Some details on this.
// Argument 1. The function to export
// Argument 2. The scope to export it to. In general this will be window,
//             or some object in the scope. While it is valid to use
//             "window", I prefer to use "unsafeWindow" if I'm exporting
//             into that scope. I find it less confusing.
// Return      This is a reference to exported function. In general you'll
//             assign this to some property of the scope you're exporting
//             into. However, it's not always neccessary. For example, if
//             you're going to use it as a callback (like for .ready())
//             then you don't need to assign it into the exported scope.
//             But if you want it globally (or scopally) accessable then
//             you need to assign it.
let exported_onReady = exportFunction(onReady, unsafeWindow);
// OR
// unsafeWindow.onReady = exportFunction(onReady, unsafeWindow);

$(document).ready(exported_onReady);
// OR
// $(document).ready(unsafeWindow.onReady);

私は今(さまざまな構成で)そのアプローチを試しましたが、何をしても許可エラーが発生し続けます。 この時点で面倒なことは本当に価値がありません。

厳しいように聞こえますが、これが邪魔にならないまで、Tampermonkeyの使用を推奨する必要があると思います。 コンテンツスクリプトは、現在の形では、実際にはユーザースクリプトのユースケースにまったく適合していません。

@obskyrに同意し、

+ 1、Tampermonkey(https://addons.mozilla.org/en-US/firefox/addon/tampermonkey/)に移動しましたが、私のスクリプトはすべてそこで機能しているようです。

+ 1、Tampermonkey(https://addons.mozilla.org/en-US/firefox/addon/tampermonkey/)に移動しましたが、私のスクリプトはすべてそこで機能しているようです。

これは短期的には機能する可能性があり、スクリプトを実行し続けることは問題なく機能しますが、長期的には、完全な置換に依存することは誤った決定である可能性があります。 短期的な成功は近視眼的かもしれません... ;-)

代わりにTMを使用していますが、いくつか問題があり、否定できません。 さらに、FF Quantumにはセキュリティ上の問題がある可能性があるため、機能しますが、単一のソリューションのみに依存するべきではありません...

とにかく、誰もがFirefoxを使用しているわけではないので、スクリプトでTMをサポートする必要があります。 つまり、GMとTMをサポートする前は、今ではTMだけです。 これまでのところ問題はありませんでした。

このページは役に立ちましたか?
0 / 5 - 0 評価