12

Web ページ内で Chrome 拡張機能を有効にする機能を探しています。

http://www.example.com/test.htmlに以下が含まれていると想像してください。

<script>
hello();
</script>

そして、私の背景ページにはhello関数の定義が含まれています:

function hello() {
    alert("test");
}

呼び出し時に Chrome 拡張機能のバックグラウンド ページhelloが呼び出されるようにするにはどうすればよいですか?test.htmlhello();

4

3 に答える 3

14

Web ページがバックグラウンド ページの関数を呼び出す前に、次の問題を解決する必要があります。

  1. hello();Webページから利用できること。これは、コンテンツ スクリプトを使用して定義するスクリプトを挿入することによって行われます。hello挿入された関数は、カスタム イベントまたは を使用してコンテンツ スクリプトと通信しますpostMessage
  2. コンテンツ スクリプトは、バックグラウンドと通信する必要があります。これは を通じて実装されますchrome.runtime.sendMessage
    Web ページも応答を受信する必要がある場合:
  3. sendMessageバックグラウンド ページ ( / onMessage、以下を参照)から返信を送信します。
  4. コンテンツ スクリプトで、カスタム イベントを作成するかpostMessage、Web ページにメッセージを送信するために使用します。
  5. Web ページで、このメッセージを処理します。

これらのメソッドはすべて非同期であり、コールバック関数を介して実装する必要があります。

これらの手順は慎重に設計する必要があります。上記のすべての手順を実装する一般的な実装を次に示します。実装について知っておくべきこと:

  • 挿入されるコードではsendMessage、コンテンツ スクリプトに接続する必要があるときはいつでもメソッドを使用します。
    使用法:sendMessage(<mixed message> [, <function callback>])

contentscript.js

// Random unique name, to be used to minimize conflicts:
var EVENT_FROM_PAGE = '__rw_chrome_ext_' + new Date().getTime();
var EVENT_REPLY = '__rw_chrome_ext_reply_' + new Date().getTime();

var s = document.createElement('script');
s.textContent = '(' + function(send_event_name, reply_event_name) {
    // NOTE: This function is serialized and runs in the page's context
    // Begin of the page's functionality
    window.hello = function(string) {
        sendMessage({
            type: 'sayhello',
            data: string
        }, function(response) {
            alert('Background said: ' + response);
        });
    };

    // End of your logic, begin of messaging implementation:
    function sendMessage(message, callback) {
        var transporter = document.createElement('dummy');
        // Handles reply:
        transporter.addEventListener(reply_event_name, function(event) {
            var result = this.getAttribute('result');
            if (this.parentNode) this.parentNode.removeChild(this);
            // After having cleaned up, send callback if needed:
            if (typeof callback == 'function') {
                result = JSON.parse(result);
                callback(result);
            }
        });
        // Functionality to notify content script
        var event = document.createEvent('Events');
        event.initEvent(send_event_name, true, false);
        transporter.setAttribute('data', JSON.stringify(message));
        (document.body||document.documentElement).appendChild(transporter);
        transporter.dispatchEvent(event);
    }
} + ')(' + JSON.stringify(/*string*/EVENT_FROM_PAGE) + ', ' +
           JSON.stringify(/*string*/EVENT_REPLY) + ');';
document.documentElement.appendChild(s);
s.parentNode.removeChild(s);


// Handle messages from/to page:
document.addEventListener(EVENT_FROM_PAGE, function(e) {
    var transporter = e.target;
    if (transporter) {
        var request = JSON.parse(transporter.getAttribute('data'));
        // Example of handling: Send message to background and await reply
        chrome.runtime.sendMessage({
            type: 'page',
            request: request
        }, function(data) {
            // Received message from background, pass to page
            var event = document.createEvent('Events');
            event.initEvent(EVENT_REPLY, false, false);
            transporter.setAttribute('result', JSON.stringify(data));
            transporter.dispatchEvent(event);
        });
    }
});

background.js

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
    if (message && message.type == 'page') {
        var page_message = message.message;
        // Simple example: Get data from extension's local storage
        var result = localStorage.getItem('whatever');
        // Reply result to content script
        sendResponse(result);
    }
});

Chrome 拡張機能はマニフェスト ファイルなしでは完全ではないためmanifest.json、回答をテストするために使用したファイルを次に示します。

{
    "name": "Page to background and back again",
    "version": "1",
    "manifest_version": 2,
    "background": {
        "scripts": ["background.js"]
    },
    "content_scripts": [{
        "matches": ["http://jsfiddle.net/jRaPj/show/*"],
        "js": ["contentscript.js"],
        "all_frames": true,
        "run_at": "document_start"
    }]
}

この拡張機能は、http://jsfiddle.net/jRaPj/show/ (hello();質問に表示されている内容を含む) でテストされ、「Background said: null」というダイアログが表示されます。
バックグラウンド ページを開き、 を使用localStorage.setItem('whatever', 'Hello!');して、メッセージが正しく変更されていることを確認します。

于 2012-12-08T17:11:48.717 に答える
3

Web ページから拡張機能にメッセージを送信する組み込みのソリューションがあります。

mainfest.json

"externally_connectable": {
  "matches": ["*://*.example.com/*"]
}

ウェブページ:

// The ID of the extension we want to talk to.
var editorExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";

// Make a simple request:
chrome.runtime.sendMessage(editorExtensionId, {openUrlInEditor: url},
  function(response) {
    if (!response.success)
      handleError(url);
  });

拡張機能のバックグラウンド スクリプト:

chrome.runtime.onMessageExternal.addListener(
  function(request, sender, sendResponse) {
    if (sender.url == blacklistedWebsite)
      return;  // don't allow this web page access
    if (request.openUrlInEditor)
      openUrl(request.openUrlInEditor);
  });
于 2016-08-19T14:23:53.380 に答える
1

いいえ、バックグラウンドページのアーキテクチャのため、上記のコードを使用してください

はい、コンテンツスクリプトで

コンテンツ スクリプトを使用したデモ

マニフェスト.json

コンテンツ スクリプト myscripts.js の登録

{
"name": "NFC",
"description": "NFC Liken",
"version": "0.1",
"manifest_version": 2,
"permissions": ["tabs", "http://*/", "https://*/"],
"content_scripts": {
    "matches": "http://www.example.com/*",
    "js": [ "myscript.js"]
  },
"browser_action": {
"default_icon": "sync-icon.png",
"default_title": "I Like I Tag"
}
}

さらに情報が必要な場合はお知らせください。

于 2012-12-08T13:48:06.523 に答える