まず、スタイルガイドを意識なさった方がよろしいかと。
どこからかコピペしてきたかのようにダブルクオート、シングルクオートが混ざり演算子間スペースが有ったり無かったり。
そういう状況ですから、if
の各所で比較演算子==
の所を代入演算子=
にしてしまって間違えているのです。
chrome拡張でコンテキストメニューから特定のURLを開いたときにそのURLのページの内容を取得しようとしていますが、contextMenus.onClickedが発生したときに新しくcreateしたtabへsendMessageを送ろうとしているのですが、cntent-script.js側で旨く受信できません。
chrom拡張のプログラムは初めて作成しているので殆ど未経験です。
解決方法を教えて下さい。
Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.
※Google JavaScript スタイルガイドを参考に、コードの修正をしました。
// background.jp
const app_url = 'https://ja.wikipedia.org/wiki/';
const msg1 = 'displayWiki';
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create({
id: 'url_open',
title: 'TEST MENU URLをOPEN',
type : 'normal',
contexts : ['page']
});
});
chrome.contextMenus.onClicked.addListener((info, tab) => {
if(info.menuItemId = 'url_open'){
console.log('url_open clicked (menuItemId=' + info.menuItemId + ')');
let creating = chrome.tabs.create({url: app_url},(tab) => {
chrome.tabs.sendMessage(tab.id,msg1,(responce) => {
console.log(responce);
});
});
};
});
content-script.jp
const msg1 = 'displayWiki';
console.log('content-script run');
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
let retMes = '(null)';
console.log('called onMessage');
console.log(sender);
if (request.name === msg1) {
console.log('resive displayWiki');
retMes = 'resive displayWiki';
};
sendResponse(retMes);
return true;
});
manifest.json
{
"manifest_version": 3,
"name": "url_jump",
"description": "url_jump",
"version": "1.0.0",
"background" : {
"service_worker" : "background.js"
},
"action":{},
"permissions" : [
"activeTab",
"scripting",
"storage",
"contextMenus",
"tabs"
],
"host_permissions": [
"https://*/*"
],
"content_scripts": [
{
"matches": ["https://ja.wikipedia.org/*"],
"js": ["content-script.js"]
}
]
}
そもそもsendMessageを使わないと出来ないのかも判りませんが、最初は開いたURLのドキュメントオブジェクトを取得する方法が見つからず、探している内にsendMessageで実現できるような解説を幾つか見つけて試しているが旨くいかないといった情況です。
よろしくお願いします。
まず、スタイルガイドを意識なさった方がよろしいかと。
どこからかコピペしてきたかのようにダブルクオート、シングルクオートが混ざり演算子間スペースが有ったり無かったり。
そういう状況ですから、if
の各所で比較演算子==
の所を代入演算子=
にしてしまって間違えているのです。
@Shujis1964
Questionerご指摘有り難うございます。わかりやすいサイトを教えて頂き助かります。
仰るとおり、取りあえず公表されているサンプルを持ってきて動かすところから始めましたので、凄く汚いコーディングになっていました。大変お恥ずかしい話です。
それなりに修正はしたのですが、エラーは変わらないので、単なるタイプミスといった類いでは無いのだと思います。
そもそもメッセージのやり取りとか、十分に理解できずに模索している状態です。
よろしくお願いします。
chrome.runtime.onMessage.addListener()
が実行されるよりも前にchrome.tabs.sendMessage()
が先走っている(早すぎる)から「Could not establish connection.」と言われ、自らメッセージを送信できない状態にしてるのです。
コピーなさったサンプルコードを掲載していたページではchrome.contextMenus.onClicked.addListener()
内部でsendMessage()
していましたか?
恐らくそのような書き方していないと思われるので、そちらよく確認なさってください。
@Shujis1964
Questioner有り難うございます。非同期の処理になれていないと言うことなのでしょうけど、
参考にしたのは
https://teratail.com/questions/137046
でして、今回は右クリックからメニュー選択で対象URLを開くようにしているので、結果的にchrome.contextMenus.onClicked.addListener()の内部に参考例のsendMessage()を入れる事になったのですが、それが良くないと言うことなのでしょうか。
この場合、sendMessage()は何処に持って行けば良いのでしょう。
日付もよく確認して下さい。とても古い情報です。
manifest_version
が2
であなたのは3
です。2
は何れ使えなくなる手法です。
上記に参考リンクを貼りましたが、そちら確認していますか?
さもなければ次のコードを理解することができません。
日本語で解説してるところもあるはずなので探してみて下さい。
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === chrome.tabs.TabStatus.COMPLETE && tab.url.startsWith('http')) {
chrome.tabs.sendMessage(tabId, "displayWiki").catch((error) => {
console.error(error);
});
}
});
chrome.tabs.onUpdated.addListener()
を使ってタブステータスが完了chrome.tabs.TabStatus.COMPLETE
したならsendMessage
する手法になります。
これであればcontent-script.js
を先に解釈するので送信可能です。
非同期処理になれてないと言うことですが、この先も必ずつきまとう問題ですから、自己学習なさってください。ここではその点についてふれません。
@Shujis1964
QuestioneronUpdatedを使ってそこでCOMPLETEを確認出来たらtabの情報を得ることが出来ました。
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (tab.status === 'complete') {
console.log('tab complete');
console.log(tab.title);
}
});
開いたtabの情報を得るのが目的だったので、これで大丈夫です。sendMessageもする必要が無かったです。
助かりました。