每当页面加载时,如何从后台向Chrome扩展程序中的弹出窗口发送消息?

问题描述:

我可以通过以下方式将消息从弹出窗口发送到后台:

I can send a message from a popup to a background via:

background.js

chrome.runtime.onMessage.addListener(
  function(request) {
    alert(request.data.subject);
  }
);

popup.js

chrome.runtime.sendMessage({
  msg: "something_completed", 
  data: {
      subject: "Loading...",
      content: "Just completed!"
  }
});

警报加载正常,但我需要做相反的事情.我希望后台在页面加载时发送一个api调用,并将该api调用的结果发送到popup.js,以便它可以对DOM进行更改.当我切换上面的代码时,没有警报显示.我的 manifest.json :

The alert loads fine BUT I need to do the opposite. I would like the background to send an api call when a page is loaded and send the results of that api call to the popup.js so that it can make changes to the DOM. When I switch the above code, no alert is shown. My manifest.json:

{
    "name": "example",
    "version": "0.0.1",
    "description": "Chrome Extension's message passing example",
    "browser_action": {
      "default_icon": "images/get_started32.png",
      "default_popup": "popup.html"
    },
    "background": {
      "scripts": ["background.js"]
    },
    "content_scripts":[{
      "matches":["http://*/*", "https://*/*"],
      "js":["popup.js"]
    }],
    "permissions": [
      "background","webRequest","webRequestBlocking","webNavigation","tabs","notifications"
    ],
    "manifest_version": 2
}

从技术上讲, chrome.runtime.sendMessage 会将消息发送到所有扩展页面,包括弹出窗口,但这不是应该组织通信的方式.

Technically, chrome.runtime.sendMessage will send a message to all extension pages including the popup, however this is not how the communication should be organized.

请注意,弹出窗口仅在显示时才运行,因此,如果隐藏了该弹出窗口,则无法接收消息.

Note, the popup is running only when shown so if it's hidden it can't receive messages.

假设弹出窗口已经可见,解决方案通常是使用 return true 来简单地等待后台脚本的响应.

Assuming the popup is already visible, the solution is usually to simply wait for the background script's response using return true.

popup.js发送一条消息:

popup.js sends a message:

chrome.runtime.sendMessage({foo: 'bar'}, response => {
  // use the response here
});

后台脚本:

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.foo === 'bar') {
    doSomeProcessing(msg).then(sendResponse);
    return true;
  }
});

function doSomeProcessing(msg) {
  return new Promise(resolve => {
    // do something async
    resolve({data: 123});
  });
}