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

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

新規登録して質問してみよう
ただいま回答率
85.51%
Chrome

Google Chromeは携帯、テレビ、デスクトップなどの様々なプラットフォームで利用できるウェブブラウザです。Googleが開発したもので、Blink (レンダリングエンジン) とアプリケーションフレームワークを使用しています。

JavaScript

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

Chrome extension

Chrome拡張機能

Q&A

解決済

1回答

4326閲覧

JavaScriptによるChrome拡張の開発で、background.js で叩いたAPIを popup.js に渡すことができない

sannye

総合スコア40

Chrome

Google Chromeは携帯、テレビ、デスクトップなどの様々なプラットフォームで利用できるウェブブラウザです。Googleが開発したもので、Blink (レンダリングエンジン) とアプリケーションフレームワークを使用しています。

JavaScript

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

Chrome extension

Chrome拡張機能

1グッド

1クリップ

投稿2017/08/08 21:46

  • popup.html を表示するときに、background.js でAPIをコールする
  • 結果をpopup.js に表示する

ということを sendMessage -> $.ajax ->sendResponse -> render
という流れでやろうとしているのですが、うまくゆきません。
render にやってくる値が undefindedになってしまいます。

JavaScriptじたいの経験が浅いゆえ、Chrome拡張の開発特有の何かというより、
JavaScriptの非同期の基礎的な取扱いでつまづいている気がします。
なにとぞよろしくお願いします。

├── asset │   └── jquery-3.2.1.min.js ├── background.js ├── manifest.json ├── popup.css ├── popup.html └── popup.js

manifest.json

{ "browser_action": { "default_popup": "popup.html" }, "permissions": ["http://*/*", "https://*/*"], "background": {"scripts": ["asset/jquery-3.2.1.min.js", "background.js"]}, "manifest_version": 2, "name": "b", "version": "0.1" }

popup.html

<script src="asset/jquery-3.2.1.min.js"></script> <link href="popup.css" rel="stylesheet"> <script src=popup.js></script>

popup.js

window.addEventListener("load", function() { chrome.runtime.sendMessage({cmd: "call_api"}, render) return false }) function render(res) { console.log(res) // sendAだけ有効, sendB, sendCはだめ }

background.js

var sending_data = {token: ""} chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { if (request.cmd == "call_api") { // sendResponse({data:"hello?"}) // sendA $.ajax( { url: 'https://api.example.com/list', type: 'post', contentType:'application/json', data: JSON.stringify(sending_data), 'crossDomain': true, success: function (res) { console.log(res) // ちゃんとデータが入っている(API叩けてる) // sendResponse({data:"hello?"}) // これがうまく呼べない // sendResponse({data: JSON.stringify(res) }) // 本当にやろうとしていること sendC }, error: console.log, }); } });
takeshih👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

これは私も戸惑いました。
メソッド内で即座に返すなら応答してくれるんですが、ajax経由で非同期で返そうとしたら成功しないんですよね。
私はこれの解決ができなくて、chrome.runtime.connectで常時接続用のポートを開いて双方向通信するというやり方をしてました。
これはこれで便利なので調べてみると良いと思います。

ただ、chrome.runtime.onMessageのヘルプを見てましたら、こう書いてありますね。

This function becomes invalid when the event listener returns, unless you return true from the event listener to indicate you wish to send a response asynchronously (this will keep the message channel open to the other end until sendResponse is called).

英語そんな得意でもないので翻訳が間違ってるかもしれませんが、
「この関数(sendResponse)は、イベントリスナーから返されるときに無効化します。
ただしイベントリスナーがtrueを返すことで、非同期で応答を送信することを示します
(sendResponseが呼び出されるまでメッセージチャネルを開いたままにします)」

ということのようです。
というわけで、

javascript

1 error: console.log, 2 }); 3 return true;// この場所! 4 } 5});

こうすれば、非同期でsendResponseを呼び出すのを待ってくれるんじゃないでしょうか?

投稿2017/08/08 22:50

編集2017/08/08 22:53
zohnam

総合スコア1441

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

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

sannye

2017/08/08 23:05

おお、同じ問題の先輩が!! 返り値でチャネルが閉じるかどうか、というのがあったとは・・・ おかげさまで、できました。本当にありがとうございます!
zohnam

2017/08/08 23:23

成功おめでとうございます。 chromeからしたら、おそらく複数のイベントリスナーに「誰か応答できませんかー」と呼びかけてるはずです。 無言で作業して後から「ん できたぞ」と返すような頑固職人的レスポンスされても困りますよね。 「ただいま作業中ですのでしばらくお待ちください」という企業的レスポンスしてくれよ、ということなのでしょう。 成功した今となってchromeの立場から考えると、そりゃそうだよなと納得いきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問