浏览器扩展:在browser-action-popup和background-script

时间:2017-01-27 13:55:23

标签: javascript google-chrome-extension firefox-webextensions

首先,我不是在寻找Long Lived Connections。我特意寻找一种发送消息并发送对这些消息的直接响应的方法。

当您在内容脚本和后台脚本之间发送消息时,它非常直接,因为您使用chrome.tabs API从/向内容脚本发送/接收消息。要从/向后台脚本发送/接收消息,请使用chrome.runtime API。

但是对于浏览器动作弹出窗口,它有点不同,因为它们都在后台环境中运行。所以我想他们都必须使用chrome.runtime API。

但这意味着我必须在浏览器动作弹出窗口和后台脚本中都听chrome.runtime.onMessage。所以基本上我会收到后台脚本中弹出窗口发送的消息,但也会弹出弹出窗口。而另一种方式是相同的。

所以是的,这不会真的有效:

/////////////background-script//////////////
//Send message from background-script to browser-action-popup
chrome.runtime.sendMessage({msg:"This is a message sent from the background-script to the browser-action-popup"})
  .then(response => { //Receive response from the browser-action-popup
      console.log(response.msg)
  })

//Receive messages from browser-action-popup
chrome.runtime.onMessage.addListener(function(message,sender,sendResponse) {
    sendResponse({msg:"This is a response message sent from the background-script"})
    return true
})

...

///////////browser-action-popup/////////////
//Send message from browser-action-popup to background-script
chrome.runtime.sendMessage({msg:"This is a message sent from the browser-action-popup to the background-script"})
  .then(response => { //Receive response from the background-script
      console.log(response.msg)
  })

//Receive message from background-script
chrome.runtime.onMessage.addListener(function(message,sender,sendResponse) {
    sendResponse({msg:"This is a response message sent from the browser-action-popup"})
    return true
})

但由于它们都是在后台环境中运行,我还想知道是否有一种比发送消息更简单的方法:是否可以在两者之间共享变量,或者它们是否完全隔离?

3 个答案:

答案 0 :(得分:2)

来自the docs

  

如果发送到您的分机,则会在您的分机的每一帧中触发runtime.onMessage事件(发件人的框架除外)

因此,您不必担心弹出窗口中弹出的消息会触发onMessage事件。

您还要通过共享变量来要求另一种沟通方式。从弹出窗口中,您可以调用chrome.runtime.getBackgroundPage,以获取后台页面的JavaScript窗口对象。在后台页面中,您可以使用{type: 'popup'}调用chrome.extension.getViews来访问弹出窗口对象(如果已打开)。

getBackgroundPage州的Firefox documentation

  

这为其他特权加载项脚本提供了一种方便的方法,可以直接访问后台脚本的作用域。这使他们能够访问该范围中定义的变量或调用函数。 “特权脚本”包括在选项页面中运行的脚本,或在浏览器操作或页面操作弹出窗口中运行的脚本,但不包括内容脚本。

答案 1 :(得分:1)

这是一个简单的,只是给你的消息类型或类似,某种消息标识符。我在这个例子中称它为类型。

/////////////background-script//////////////
//Send message from background-script to browser-action-popup
var msg = {
    data : "This is a message sent from the background-script to the browser-action-popup",
    type : "notifyPopupOfMessage"
};

chrome.runtime.sendMessage(msg)
.then(response =  > { //Receive response from the browser-action-popup
        console.log(response.data);
    })

//Receive messages from browser-action-popup
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
    if (message.type === 'notifyBackgroundOfMessage') {
        var msg = {
            data : "This is a response message sent from the background-script",
            type: 'notifyPopupOfMessage'
        };

        sendResponse(msg);
    }

    return true
});

.....

///////////browser-action-popup/////////////
//Send message from browser-action-popup to background-script

var msg = {
    data: 'This is a message sent from the browser-action-popup to the background-script',
    type: 'notifyBackgroundOfMessage'
};

chrome.runtime.sendMessage(msg)
  .then(response => { //Receive response from the background-script
      console.log(response.data);
  });

//Receive message from background-script
chrome.runtime.onMessage.addListener(function(message,sender,sendResponse) {
    if(message.type === 'notifyPopupOfMessage') {
        var msg = {
            data:"This is a response message sent from the browser-action-popup",
            type: 'notifyBackgroundOfMessage'
        };
        sendResponse(msg);
    }

    return true
});

希望有所帮助。

答案 2 :(得分:0)

虽然Daniel Lane的答案理论上可行,但我并不喜欢使用msg对象来识别发件人。我实际上找到了一种巧妙的方法来过滤掉同一个"页面" (backgorund,popup等)。
我通过识别当前页面网址并将其与sender.url进行比较来完成。这是我的全部代码:

<强> popup.js

const THIS_PAGE_URL = chrome.runtime.getURL('popup.html')

//Send message from browser-action-popup to background-script
setTimeout(function(){

    chrome.runtime.sendMessage({msg:"This is a message sent from the browser-action-popup to the background-script"})
      .then(response => { //Receive response from the background-script
          if (!response) {
              console.log("Popup sent a msg and received no response.")
              return
          }
          document.body.innerHTML += "<br>Popup sent a msg and received a response: " + response.msg
      })

}, 3000)


//Receive message from background-script
chrome.runtime.onMessage.addListener(function(message,sender,sendResponse) {
    if (sender.url === THIS_PAGE_URL)
        return
    document.body.innerHTML += "<br>Popup received a new msg: " + message.msg
    sendResponse({msg:"This is a response message sent from the browser-action-popup"})
    return true
})

<强>背景的script.js

const THIS_PAGE_URL = chrome.runtime.getURL('_generated_background_page.html')

//Send message from background-script to browser-action-popup
setTimeout(function(){

    chrome.runtime.sendMessage({msg:"This is a message sent from the background-script to the browser-action-popup"})
      .then(response => { //Receive response from the browser-action-popup
          if (!response) {
              console.log("Background-script sent a msg and received no response.")
              return
          }
          console.log("Background-script sent a msg and received a response: " + response.msg)
      })

},3000)


//Receive messages from browser-action-popup
chrome.runtime.onMessage.addListener(function(message,sender,sendResponse) {
    if (sender.url === THIS_PAGE_URL)
        return
    console.log("Background-script received a new msg: " + message.msg)
    sendResponse({msg:"This is a response message sent from the background-script"})
    return true
})

对于那些感兴趣的人来说,剩下的文件是:

<强> popup.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <script src="popup.js"></script>
  </body>
</html>

<强>的manifest.json

{
  "manifest_version": 2,
  "name": "popup-background-msg-example",
  "version": "1.0",

  "browser_action": {
    "browser_style": true,
    "default_title": "popup-background-msg-example",
    "default_popup": "popup.html"
  },

  "background": {
    "scripts": ["background-script.js"]
  }
}