質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Firefox WebExtensions

Firefox WebExtensionsは、Firefox向けアドオンをクロスブラウザで開発するためのAPIおよび技術。Google Chrome/Operaでサポートされているextension API との互換性を持ちます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Chrome extension

Chrome拡張機能

Q&A

解決済

1回答

12218閲覧

WebExtensionsのtabs.sendMessageが動かない

nekojiro

総合スコア43

Firefox WebExtensions

Firefox WebExtensionsは、Firefox向けアドオンをクロスブラウザで開発するためのAPIおよび技術。Google Chrome/Operaでサポートされているextension API との互換性を持ちます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Chrome extension

Chrome拡張機能

0グッド

0クリップ

投稿2017/03/15 03:22

編集2017/03/15 06:14

###前提・実現したいこと
WebExtensionsでyoutubeの動画を新しいウインドウで開くアドオンを作っています。
なぜか最初にインストールした時だけbrowser.tabs.sendMessageがエラーを出します。ブラウザーを再起動すると直ります。これはバグなんでしょうかそれとも僕の書き方が悪いんでしょうか。

###発生している問題・エラーメッセージ

Error: Error: Could not establish connection. Receiving end does not exist. YouTube-background.js:2:3 onError moz-extension://31a62720-6f34-4d04-9287-0b9c07dc7cf3/YouTube-background.js:2:3 (非同期: promise callback) newWindow/< moz-extension://31a62720-6f34-4d04-9287-0b9c07dc7cf3/YouTube-background.js:10:5 (非同期: promise callback) newWindow moz-extension://31a62720-6f34-4d04-9287-0b9c07dc7cf3/YouTube-background.js:8:3 onGot/</< moz-extension://31a62720-6f34-4d04-9287-0b9c07dc7cf3/YouTube-background.js:39:9 (非同期: promise callback) onGot/< moz-extension://31a62720-6f34-4d04-9287-0b9c07dc7cf3/YouTube-background.js:38:7 (非同期: promise callback) onGot moz-extension://31a62720-6f34-4d04-9287-0b9c07dc7cf3/YouTube-background.js:25:5 (非同期: promise callback) getInfoForTab moz-extension://31a62720-6f34-4d04-9287-0b9c07dc7cf3/YouTube-background.js:48:5 (非同期: promise callback) <匿名関数> moz-extension://31a62720-6f34-4d04-9287-0b9c07dc7cf3/YouTube-background.js:54:3

###該当のソースコード
manifest.json

json

1{ 2 "manifest_version": 2, 3 "name": "YouTube Popup Panel", 4 "version": "1.2", 5 "applications": { 6 "gecko": { 7 "id": "YouTube-Popup-Panel@nekojiro.net" 8 } 9 }, 10 "description": "__MSG_extensionDescription__", 11 "default_locale": "en", 12 "background": { 13 "scripts": ["YouTube-background.js"] 14 }, 15 "page_action": { 16 "default_icon": "icons/page-32.png", 17 "default_title": "Popup" 18 }, 19 "icons": { 20 "48": "icons/page-48.png", 21 "64": "icon/page-64.png" 22 }, 23 "permissions": [ 24 "storage", 25 "tabs" 26 ], 27 "options_ui": { 28 "page": "options/options.html" 29 } 30}

background

javascript

1function onError(error) { 2 console.error(`Error: ${error}`); 3} 4 5function newWindow(YouTubeURL) { 6 const videoID = YouTubeURL.slice(32); 7 const querying = browser.tabs.query({currentWindow: true, active: true}); 8 querying.then((tabs) => { 9 console.log(tabs[0].id); 10 browser.tabs.sendMessage(tabs[0].id, {URL: videoID}).catch(onError); 11 }); 12 /* browser.windows.onCreated.addListener(() => { 13 }); 14 browser.windows.onCreated.removeListener(newWindow); */ 15} 16 17function onGot(tabInfo) { 18 const YouTubewatchURL = 'https://www.youtube.com/watch'; 19 if (tabInfo.url.match(YouTubewatchURL)) { 20 let width = 960; 21 let height = 540; 22 const gettingWidth = browser.storage.local.get('width'); 23 const gettingHeight = browser.storage.local.get('height'); 24 const popupURL = browser.extension.getURL('popup/popup.html'); 25 Promise.all([gettingWidth, gettingHeight]).then(results => { 26 if (results[0] && results[0].width) { 27 width = parseInt(results[0].width, 10); 28 } 29 if (results[1] && results[1].height) { 30 height = parseInt(results[1].height, 10); 31 } 32 const creating = browser.windows.create({ 33 url: popupURL, 34 type: 'panel', 35 width: width, 36 height: height, 37 }); 38 creating.then(() => { 39 newWindow(tabInfo.url); 40 }); 41 }); 42 } 43} 44 45function getInfoForTab(tabs) { 46 if (tabs.length > 0) { 47 const gettingInfo = browser.tabs.get(tabs[0].id); 48 gettingInfo.then(onGot); 49 } 50} 51 52browser.pageAction.onClicked.addListener(() => { 53 const querying = browser.tabs.query({currentWindow: true, active: true}); 54 querying.then(getInfoForTab); 55}); 56 57function updateActiveTab(tabs) { 58 function onGot(tabInfo) { 59 const YouTubewatchURL = 'https://www.youtube.com/watch'; 60 if (tabInfo.url.match(YouTubewatchURL)) { 61 browser.pageAction.show(tabs); 62 } 63 } 64 const gettingInfo = browser.tabs.get(tabs); 65 gettingInfo.then(onGot); 66} 67// listen to tab URL changes 68browser.tabs.onUpdated.addListener((tabId, changeInfo) => { 69 if (changeInfo.status === 'complete') { 70 console.log(tabId); 71 updateActiveTab(tabId); 72 } 73}); 74// listen to tab switching 75browser.tabs.onActivated.addListener((activeInfo) => { 76 updateActiveTab(activeInfo.tabId); 77});

新しいウインドウのhtmlが読み込んでるjs

javascript

1browser.runtime.onMessage.addListener(getURL);

###試したこと
エラーを調べてみたけれどわからなかった。

###補足情報(言語/FW/ツール等のバージョンなど)
firefox developer edition 54.0a2
firefox 64bit 52.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

turbgraphics200

2017/03/15 04:47

onGot()はどのタイミングで呼ばれるのでしょうか
nekojiro

2017/03/15 04:51

tabs.onUpdated.addListenerとonActivated.addListenerのどちらかが作動したらです。コードを全部乗せたほうがいいですか?
turbgraphics200

2017/03/15 05:48 編集

ううむ、私の環境では再現しませんね。(Win10, FF52 DE54.0a2)
turbgraphics200

2017/03/15 06:11

ううむ、URLからインストールしてみましたが、やはり私の環境では再現しませんでした。
guest

回答1

0

ベストアンサー

そのエラーは、 sendMessage を送る先で browser.runtime.onMessage.addListener が設定されていないときにおきます。

例えば、

javascript

1browser.pageAction.onClicked.addListener(async _ => { 2 const tabs = await browser.tabs.query({currentWindow: true, active: true}) 3 const tabid = tabs[0].id 4 browser.tabs.sendMessage(tabid , {data: 100}) 5 .then(e => console.log(e)).catch(e => console.error(e)) 6 // Error: Could not establish connection. Receiving end does not exist. 7})

これだけで 送り先のタブで何も設定していないとエラーが発生します

Error: Could not establish connection. Receiving end does not exist.

送り先で設定されていると

javascript

1browser.pageAction.onClicked.addListener(async _ => { 2 const tabs = await browser.tabs.query({currentWindow: true, active: true}) 3 const tabid = tabs[0].id 4 await browser.tabs.executeScript(tabid, { 5 code: ` 6 browser.runtime.onMessage.addListener(async request => { 7 console.log(request) 8 return {response: "ok"} 9 }) 10 ` 11 }) 12 browser.tabs.sendMessage(tabid, {data: 100}) 13 .then(e => console.log(e)).catch(e => console.error(e)) 14 // Object { response: "ok" } 15})

このように browser.runtime.onMessage.addListener での返り値を受け取れます。

今回の場合、 tabid は拡張機能の popup.html のものになるかと思いますので、 JavaScript を埋め込む必要はなく、 popup.html でこんな風に browser.runtime.onMessage.addListener を設定すればいいです。

html

1<!doctype html> 2<meta charset="utf-8"/> 3 4<script src="popup.js"></script>

[popup.js]

javascript

1browser.runtime.onMessage.addListener(async request => { 2 console.log(request) 3 return {response: "ok"} 4})

ただ、今のコードだと sendMessage のタイミングではまだ開いてページのロードが完了していないようで、 about:blank となっていました。

browser.runtime.onMessage.addListener が正しく設定できているならロード済みになるのを待ってから sendMessage するだけで動くのではと思います。

あと、たしか拡張機能のページだと tabs でなく runtime で通信できたと思います。(Chrome では。Firefoxは試してないです)


コピペの影響でコードに統一性がなかったのでちょっと修正しました

投稿2017/03/16 17:07

編集2017/03/16 17:25
ryls-nmm

総合スコア633

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nekojiro

2017/03/17 06:45 編集

asyncを付けても動きませんでした。
nekojiro

2017/03/17 07:02

browser.tabs.onUpdated.addListener((tabId, changeInfo) => { if (changeInfo.status === 'complete') { const querying = browser.tabs.query({currentWindow: true, active: true}); querying.then((tabs) => { browser.tabs.sendMessage(tabs[0].id, {URL: videoID}).catch(onError); }); } }); browser.tabs.onUpdated.removeListener; ページのロードを待ったら動きました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問