Translate

BTemplates.com

Powered by Blogger.

2019年8月31日土曜日

Chrome拡張のUnchecked runtime.lastError: Could not establish connection. Receiving end does not exist.というエラーを解決する


◆事の起こり

 Chrome拡張を作成している際に、ボタンをクリックしたときに
ブラウザの開いている全てのタブのURLが欲しい場面があった。

それ自体は、chrome.tabs.queryで取得できるのだが、
chrome.tabs.queryは、background.jsでないと動かないので
content_script.jsとbackground.jsで通信する必要があった。

しかし、content_script.jsでchrome.runtime.sendMessageを使って
background.jsに送信し、background.jsでchrome.runtime.onMessage.addListener
を使って受診し、sendResponseで送り返しているはずなのだが、
Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.というエラーがログに表示された。


◆解決方法

私の場合だと、以下の三つを行うことで解決できた。

1.manifest.jsonに以下の内容が記述していなかった。
  "background": {
    "scripts": [
      "src/js/background.js"
    ]
  },

2.chrome.runtime.onMessage.addListener()のfunctionの中の一番最後に
return trueを記述していない

3.修正後も拡張機能のページ(chrome://extensions/)のエクステンションの更新ボタンをクリックして更新していなかった為である。




◆実際に試したこと

調べたところ、ネットに出ているのは試したのは以下の二つである。
・ほかの拡張機能が悪さをしているので、他の拡張機能を全部オフにしよう。
・エラー名の通り接続できていないので、接続できるまでsetTimeout()で呼び出せばいいんじゃないのか?

結論から言えば、今回のケースだと全部駄目だった。

なお、最初に記述した忙しい人の為の解決方法の内容を全て行った上で
仮にsetTimeoutのやり方で実装する場合は
以下のように実装すれば動くことは確認できた。

var getTabUrlsButton =
  '<button type="button" class="get_tab_urls_button">ブラウザのタブのURL取得</button>';
$ ('.getTabsUrlsButton').append (getTabUrlsButton);
$ ('.get_tab_urls_button').click (function (e) {
  ping ();
});
function ping () {
  chrome.runtime.sendMessage ({}, function (response) {
    if (chrome.runtime.lastError) {
      setTimeout (ping, 1000);
    } else {
      if (response) {
        $ ('.getTabUrlText').html (response.urls);
      }
    }
  });
}


*参考サイト

・特定のChrome拡張機能をOFFにするとエラーが消える事を検証している動画
Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.(YouTube)
・上と同じく特定のChrome拡張機能をOFFにするとエラーが消えるという話をしている
node.js - How to fix 'Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.' - Stack Overflow

・回答の一例でのsetTimeoutの話を参考にさせてもらった
Chrome Extension message passing: Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist - Stack Overflow


◆その他

・調べてもpop.jsとbackground.jsの通信による結果のケースが多く
content_script.jsは特別なケースなのかと思っていたが、単にcontent_script.jsで書く人がいなかっただけのようだった。

・background.jsから、content_script.jsにデータを渡す際にタブのIDの指定が必要だという情報をネットで見かけたが、今回の件に限って言えば必要なかった。

・これとは直接は関係ないが、chrome.tabs.query()を使った際にsendResponse()を
chrome.tabs.query()のfunction外で宣言すると、chrome.tabs.query()が非同期なので
値を取得できずに初期値しか返さない。その為、きちんと動いているように見えるのに初期値しか返さなくて凄く混乱したことがあった。
これは、細かくconsole.logを使う事で明らかに呼び出しの順番がおかしい事に気が付くことで、なんとか判明することができた。


◆サンプル

content_script.jsとbackground.js間で通信をして
タブのURLを取得するChrome拡張を作りました。
gitを上げたので良ければ参考にしてください。
https://github.com/nononaga/myExample/tree/master/getTabUrls


0 コメント:

コメントを投稿