今回は、chrome拡張機能のバックグラウンドやアクション、コンテンツスクリプトを連携(値を送ったり、受け取ったり)するのに必要なメッセージパッシングについて解説しようと思います。
コンテキストメニュー(右クリック)の実装の必要がないコンテンツスクリプトだけの拡張機能や前記事で解説しましたmemo memoのようなポップアップで入力・保存・表示するだけの拡張機能にはメッセージパッシングは必要はありませんが、ポップアップで設置したボタンを押した際に、コンテンツスクリプトでDOMの要素を取得したりDOMの要素にポップアップで入力した値を入力したりする拡張機能になるとメッセージパッシングは必須になります。
メッセージパッシングとは、chrome拡張機能において、お互いが直接干渉できない世界で通信をするための決まり事という風に考えていただいて良いと思います。
メッセージパッシングを使ってchrome拡張機能内で値を受け渡す
コンテンツスクリプト→chrome拡張側スクリプト
コンテンツスクリプト(Webページに適用するスクリプト)からchrome拡張側のスクリプト(ポップアップやservice_worker)にメッセージを送信するには、『chrome.runtime.sendMessage()』を使用します。
第一引数の送信するデータにはオブジェクトを指定することも可能なようです。
// 送信側
chrome.runtime.sendMessage('送りました', function (response) {
// ここに受信側からレスポンスが返ってきた時にする処理を記述する。
console.log(response); // sendResponse で送り返された '送ってくれてありがとう' が表示される
});
コンテンツスクリプト(Webページに適用するスクリプト)がchrome拡張側のスクリプト(ポップアップやservice_worker)からメッセージを受信するには、『chrome.runtime.onMessage()』を使用します。
sendResponseを使えば受信するだけでなく送信側に情報を返すこともできます。
//受信側
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
console.log(request); // 文字'送りました'が返ってくる
console.log(sender); // 送信時のタブの情報が返ってくる(タブのIDやURLなどの情報)
sendResponse('送ってくれてありがとう'); // 送信側に送り返したい情報を記入する
});
chrome拡張側スクリプト→コンテンツスクリプト
chrome拡張側のスクリプト(ポップアップやservice_worker)からコンテンツスクリプト(Webページに適用するスクリプト)へメッセージを送信するには、『chrome.tabs.sendMessage』を使用します。
chrome.tabs.sendMessagの第一引数に送信するタブのIDが必要なため、chrome.tabs.queryでタブの情報を取得しています。
//送信側
//chrome.tabs.queryでタブの情報を取得する(chrome.tabs.sendMessageの際に送信するタブのIDが必要なため)
chrome.tabs.query({
active: true,
currentWindow: true
}, function (tab) {
// chrome.tabs.sendMessageの第二引数は送信する情報(自由に決めて可)。
chrome.tabs.sendMessage(tab[0].id, '送りました', function (response) {
//ここに受信側からレスポンスが返ってきた時にする処理を記述する。
console.log(response); //sendResponse で送り返された '送ってくれてありがとう' が表示される
})
})
chrome拡張側のスクリプト(ポップアップやservice_worker)がコンテンツスクリプト(Webページに適用するスクリプト)からメッセージを受信するには、『chrome.runtime.onMessage()』を使用します。
//受信側
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
console.log(request); // 文字'送りました'が返ってくる
console.log(sender); // 送信時のタブの情報が返ってくる(タブのIDやURLなどの情報)
sendResponse('送ってくれてありがとう'); // 送信側に送り返したい情報を記入する
})
以下に、箇条書きでコンテンツスクリプトとサービスワーカー間でのメッセージパッシングの手順の説明をまとめてみました。
- コンテンツスクリプトからのメッセージ送信:
- コンテンツスクリプト内で、
chrome.runtime.sendMessage()
メソッドを使用してメッセージを送信します。 - 送信するメッセージは、オブジェクト形式で指定します。必要に応じてデータや任意のパラメータを含めることができます。
- コンテンツスクリプト内で、
- サービスワーカーでのメッセージ受信:
- サービスワーカー内で、
chrome.runtime.onMessage
イベントをリッスンしてメッセージを受信します。 - イベントハンドラ内で、受信したメッセージを処理します。
- サービスワーカー内で、
- サービスワーカーからのメッセージ送信:
- サービスワーカー内で、
chrome.tabs.sendMessage()
メソッドを使用してメッセージを送信します。 - 送信するメッセージのターゲットとなるタブを指定する必要があります。通常、タブIDやタブのURLを使用して特定のタブに送信します。
- サービスワーカー内で、
- コンテンツスクリプトでのメッセージ受信:
- コンテンツスクリプト内で、
chrome.runtime.onMessage
イベントをリッスンしてメッセージを受信します。 - イベントハンドラ内で、受信したメッセージを処理します。
- コンテンツスクリプト内で、
このようにして、コンテンツスクリプトとサービスワーカー間でデータを送受信することができます。メッセージパッシングを使用することで、拡張機能内の異なるコンポーネント間で情報を共有したり、タスクを委任したりすることができます。
注意点として、メッセージパッシングは非同期的な操作であり、データの送信と受信が即座に行われない場合があります。そのため、適切なコールバックやプロミスの処理を行うことが重要です。また、メッセージパッシングには制限があり、送信可能なデータのサイズに制限があることにも注意が必要です。
まとめ
以上、javascript超初心者が解説するchrome拡張機能のメッセージパッシングについてのお話でした。
間違っている箇所もあるかと思いますので(なんせまだfor文も書いたことが無いプログラミング初心者なので・・・(笑))色んな方の記事を参考にchrome拡張機能についての知識を吸収していってもらえればと思います。
またご感想・ご指摘等ありましたらコメントしていただければ幸いです。
記事を最後までお読みいただきありがとうございました。
それでは、さようなら。
コメント
コメント一覧 (7件)
[…] あと、backgroundとcontent_scriptsの送受信の関係などが記載されているサイトを見つけたので、そちらもリンクを貼っときます、こちらのページになります。 […]
popup.jsからcontent_scritptsに送信するのはよく見つかったのですが、逆のcontent_scritptsからpopup.jsに送信する方法が見つけられなかったため非常に参考になりました。ありがとうございます。
コメントありがとうございます。
こんな初心者のブログを見てくださりありがとうございます!
じゃんじゃん拡張機能作ってください!
Pretty section of content. I just stumbled upon your weblog and in accession capital to claim that I acquire actually enjoyed account your blog posts.
Any wayy I will bbe subscribing on your feeds or even I achievement you get right of ejtry to consistently rapidly. https://Lvivforum.Pp.ua/
Thank you for your comment! I’m glad you’re enjoying the blog. We will continue to do our best to provide you with useful information, so please come visit us again!
Great explanation! Message passing is indeed essential for Chrome extensions that interact with the DOM, as it bridges communication between isolated parts of the extension. Thanks for clarifying when it’s necessary and how it works!
Thank you for visiting my blog. Although I’m not an engineer and don’t have extensive knowledge, I’m glad I could be of help to you.