CHROME扩展开发之·消息传递Message(window.message)

由于content scripts运行在Web页面的上下文中,属于Web页面的组成部分,而不是Google Chrome扩展程序。但是content scripts又往往需要与Google Chrome扩展程序的其他部分通信以共享数据。
这可以通过消息传递实现,通过彼此互相的消息的监听与反馈进行通信。一个消息可以包含任何有效的JSON对象,如null,boolean,number,string,array,object。

一次性请求与响应模式

对于一次性请求与响应模式,chrome.runtime.sendMessage(obj, function(response){})是从content scripts发生请求消息给Google Chrome扩展程序页面。

从Google Chrome扩展程序页面发送请求消息给content scripts的时候,需要给出当前tab的ID。

chrome.tabs.query(
    {active: true, currentWindow: true},
    function(tabs) {
          chrome.tabs.sendMessage(
            tabs[0].id,
            {greeting: "hello"},
            function(response) {
                    console.log(response.farewell);
        });
});

监听消息时,需要注册要监听的消息。

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");
    if (request.greeting == "hello")//判断是否为要处理的消息
      sendResponse({farewell: "goodbye"});
});

注意:如果为同一个消息注册了多个监听器,则只有第一个监听器能够调用sendResponse()方法,其他的监听器将被忽略。

保持长期连接的模式

对于保持长期连接的模式,在content scripts与Chrome扩展程序页面之间建立通道(可以为通道命名),可以处理多个消息。在通道的两端分别拥有一个chrome.runtime.Port对象,用以收发消息。

在content scripts主动建立通道如下:

var port = chrome.runtime.connect({name: "yisheng"});//通道名称
port.postMessage({joke: "Knock knock"});//发送消息
port.onMessage.addListener(function(msg) {//监听消息
  if (msg.question == "Who's there?")
    port.postMessage({answer: "yisheng"});
  else if (msg.question == "Madame who?")
    port.postMessage({answer: "Madame... Bovary"});
});

在Google Chrome扩展程序页面主动建立通道如下:

chrome.tabs.query(
    {active: true, currentWindow: true},
    function(tabs) {
          var port = chrome.tabs.connect(//建立通道
            tabs[0].id,
            {name: "yisheng"}//通道名称
        );
});

在content scripts或Google Chrome扩展程序页面,监听建立连接的请求如下:

chrome.runtime.onConnect.addListener(function(port) {
  console.assert(port.name == "yisheng");
  port.onMessage.addListener(function(msg) {
    if (msg.joke == "Knock knock")
      port.postMessage({question: "Who's there?"});
    else if (msg.answer == "Madame")
      port.postMessage({question: "Madame who?"});
    else if (msg.answer == "Madame... Bovary")
      port.postMessage({question: "I don't get it."});
  });
});

在content scripts或Google Chrome扩展程序页面的任一端,调用chrome.runtime.Port.disconnect()则关闭连接,同时出发disconnect事件。这时,只有另一端监听chrome.runtime.Port.onDisconnect事件,则可以知道连接关闭。

Google Chrome扩展程序之间消息模式

还可以在不同的Google Chrome扩展程序之间发送消息,只要知道Google Chrome扩展程序的ID。这使得Google Chrome扩展程序可以发布服务为其他扩展程序所用。

这种Google Chrome扩展程序之间的消息也分为一次性请求与响应模式和保持长期连接的模式。

Google Chrome扩展程序监听调用其服务的消息如下:

//一次性请求与响应模式:
chrome.runtime.onMessageExternal.addListener(
  function(request, sender, sendResponse) {
    if (sender.id == blacklistedExtension)//黑名单
      return;  // don't allow this extension access
    else if (request.getTargetData)
      sendResponse({targetData: targetData});
    else if (request.activateLasers) {
      var success = activateLasers();
      sendResponse({activateLasers: success});
    }
  });

//保持长期连接的模式:
chrome.runtime.onConnectExternal.addListener(function(port) {
  port.onMessage.addListener(function(msg) {
    // See other examples for sample onMessage handlers.
  });
});

发送调用服务的消息如下:

// The ID of the extension we want to talk to.
var laserExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";

// Make a simple request:
chrome.runtime.sendMessage(laserExtensionId, {getTargetData: true},
  function(response) {
    if (targetInRange(response.targetData))
      chrome.runtime.sendMessage(laserExtensionId, {activateLasers: true});
  });

// Start a long-running conversation:
var port = chrome.runtime.connect(laserExtensionId);
port.postMessage(...);

Google Chrome扩展程序接收指定的Web页面发送的消息

Google Chrome扩展程序可以与一些指定地点Web页面直接收发消息。

首先,在Google Chrome扩展程序的manifest.json文件设置可以通信的Web页面范围:

"externally_connectable": {
	"matches": ["*://*.example.com/*"]
}

其次,在Google Chrome扩展程序中监听Web页面的消息如下:

chrome.runtime.onMessageExternal.addListener(
  function(request, sender, sendResponse) {
    if (sender.url == blacklistedWebsite)
      return;  // don't allow this web page access
    if (request.openUrlInEditor)
      openUrl(request.openUrlInEditor);
});

最后,在指定的Web页面中,发送消息如下:

// The ID of the extension we want to talk to.
var editorExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";

// Make a simple request:
chrome.runtime.sendMessage(editorExtensionId, {openUrlInEditor: url},
  function(response) {
    if (!response.success)
      handleError(url);
});
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值