4

私はブラウザの拡張機能/アドオンに取り組んでいます。Chromeで動作しているので、Firefoxで動作させようとしています。

アドオンを Firefox Developer Edition 49.0a2 (2016-07-25) にロードするようになりました。

私の拡張機能には content_script が に設定されてrun_at: document_startいるため、他のページ スクリプトが実行される前にスクリプト タグを挿入できるため、オブジェクトを Web サイトでグローバルに利用できるようになります。

これは Chrome では正常に機能しているように見えますが、Firefox では、ほとんどの場合、他のページ リソースが最初に読み込まれるため、多少の競合状態であることが証明されています。

他のページ スクリプトが実行される前にスクリプトを挿入してロードできるように、コンテンツ スクリプトをロードする戦略はありますか?

ログを追加すると、何が起こっているのかをうまく切り分けることができます。このコンテンツ スクリプトの例では、次のようになります。

// inject in-page script
console.log('STEP 1, this always happens first')
var scriptTag = document.createElement('script')
scriptTag.src = chrome.extension.getURL('scripts/inpage.js')
scriptTag.onload = function () { this.parentNode.removeChild(this) }
var container = document.head || document.documentElement
// append as first child
container.insertBefore(scriptTag, container.children[0])

ファイルscripts/inpage.jsが単にログを実行する場合、

console.log('STEP 2, this should always run second')

そして、次のようなスクリプトを含むページにアクセスします。

console.log('Step 3, the page itself, should run last')

実際には、ステップ 2 とステップ 3 は非決定的な順序で実行されます。

どうもありがとう!

自分で試す勇気がある場合は、特別なブランチの公開リポジトリに Firefox 互換バージョンのスクリプトがあります: https://github.com/MetaMask/metamask-plugin/tree/FirefoxCompatibility

4

2 に答える 2

5

外部ソース ( <script src>) を使用して動的に挿入されたスクリプトは、スクリプトの実行をブロックしないため、スクリプトが読み込まれるという保証はありません。拡張機能が Chrome で機能した場合は、運が良かっただけです。

他のスクリプトよりも先にスクリプトを実行したい場合は、インラインで実行する必要があります。

var actualCode = `
// Content of scripts/inpage.js here
`;

var s = document.createElement('script');
s.textContent = actualCode;
(document.head || document.documentElement).appendChild(s);
s.remove();

理想的には、ビルド スクリプトは を読み取りscripts/inpage.js、それを文字列にシリアル化し、actualCode変数に入れます。しかしinpage.js、ほんの数行のコードであれば、上記を使用できます。

どうしても必要な場合を除き、Web ページにコードを挿入しないでください。その理由は、ページの実行環境が信頼されていないためです。at に注入するdocument_startと、後で (クロージャで) 使用する関数と (プロトタイプ) メソッドを保存できますが、非常に慎重なコーディングが必要です。

コンテンツ スクリプトがビルド スクリプトによって生成されず、スクリプトを分離したままにしておく場合は、同期を使用XMLHttpRequestしてスクリプトをフェッチすることもできます。同期 XHR はパフォーマンス上の理由から推奨されていないため、自己責任で使用してください。通常、拡張コードは拡張機能にバンドルされているため、sync xhr の使用はリスクが低いはずです。

// Note: do not use synchronous XHR in production!
var x = new XMLHttpRequest();
x.open('GET', chrome.runtime.getURL('scripts/inpage.js'), false);
x.send();
var actualCode = x.responseText;

var s = document.createElement('script');
s.textContent = actualCode;
(document.head || document.documentElement).appendChild(s);
s.remove();
于 2016-07-25T22:41:31.073 に答える
0

bootstrap.js ベースのアドオンを使用している場合は、フレームスクリプトを使用しDOMWindowCreatedて、HTML DOM (過去の document.body などの基本) がレンダリングされる前にドキュメントを操作できます - https://developer.mozilla.org/en-US /Firefox/Multiprocess_Firefox/Frame_script_environment#Events - innerHTML は利用できますが、スクリプトは実行されません。@Robが述べたように、インラインスクリプトを一番上に置くことができます。

于 2016-07-26T03:41:27.253 に答える