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

2023-11-17

由于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);
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CHROME扩展开发之·消息传递Message(window.message) 的相关文章

随机推荐

  • C++ 引用

    引用变量是一个别名 也就是说 它是某个已存在变量的另一个名字 一旦把引用初始化为某个变量 就可以使用该引用名称或变量名称来指向变量 引用和指针 引用很容易与指针混淆 它们之间有三个主要的不同 不存在空引用 引用必须连接到一块合法的内存 一旦
  • MinGW-w64下载文件失败the file has been downloaded incorrectly

    文章目录 前言 必读 1 问题背景 2 报错原因 3 解决方案 前言 必读 笔者强烈推荐使用 linux平台 搭建C 环境所需的东西 如果是用windows平台 则会出现很多小问题 或者即使安装好了 程序跑起来的时候仍会有问题 如果是单纯想
  • The Raft Group [naming_instance_metadata] did not find the Leader node;caused: The Raft Group

    1 异常信息 caused errCode 500 errMsg do metadata operation failed caused com alibaba nacos consistency exception Consistency
  • 安装MySQL(无管理员权限)

    Install MySQL without administrator permission Step 1 Download https cdn mysql com Downloads MySQL 5 7 mysql 5 7 24 win3
  • “echo 0 > /proc/sys/kernel/hung_task_timeout_secs“ disables this message

    现象 主机无缘无故死机 主机上服务无响应 日志出现大量 echo 0 gt proc sys kernel hung task timeout secs disables this message 日志输出信息 分析 echo 0 gt p
  • Future异步

    Future异步是Java中常用的异步编程方式之一 它能够在代码执行过程中返回一个代表未来结果的Future对象 使得程序能够在等待结果的同时继续执行其他操作 本文将从Future异步的定义 使用方法和优缺点等方面对其进行详细介绍 一 Fu
  • Qt信号发送过快,槽函数处理不过来解决方法

    问题 跨线程使用信号与槽连接 信号的发送时间间隔小于槽函数处理的时间间隔 造成的问题 子线程下的槽函数 用sleep来模拟槽函数的耗时操作 void MyThread myTimeout qDebug lt lt test QThread
  • 矩阵转置代码,速度优化

    今天心血来潮 想写个CPU版本的矩阵转置代码 过几天写GPU版本的 按照我的想法 就是以下几种方式 1 gt 整块矩阵转置 横读纵写或纵读横写 2 gt 将矩阵分成固定大小的block block与block可以分成横读纵写或纵读横写 而b
  • const修饰成员函数

    常函数 成员函数后加const后 我们称这个函数为常函数 在常函数内不可以修改成员的属性 成员属性声明时加关键字mutable后 在常函数中依然可以修改 常对象 声明对象前加const称该对象为常对象 常对象不能在类外修改其成员属性 但可以
  • K8s(Kubernetes)工具

    文章目录 Kubernetes简介 kubernetes背景和历史 kubernetes特点 kubernetes相关概念 基本对象 Pod Service Volume 持久存储卷 Persistent Volume PV 和持久存储卷声
  • linux怎么用python运维命令_运维笔记--linux环境提示python: command not found

    场景描述 新部署的容器环境 终端执行python命令 提示没有该命令 从报错异常可以看出 可能是python环境未安装 分析思路 检查python路径 方式一 type a python 方式二 ls l usr bin python ls
  • 【python总结】python学习框架梳理

    目录 基础 注释与变量名等基本规则 关键字 操作符 数字 流程控制 序列 文本序列 字符串 二进制序列 字节 列表 元组 映射 字典 集合 函数 面向对象编程 错误和异常 模块 数据结构与算法 数组 字符串 链表 二分查找 排序 栈 队列
  • 企业微信回调-通讯录改变回调

    https work weixin qq com api doc 90000 90135 90966 先配置url token encodingAESKey import com ichangtou common util AesExcep
  • Maven环境正常,打包后使用报 java.lang.NoClassDefFoundError: javax/servlet/ServletInputStream 错误

    也是找的网上的解决方法 下载一个tomcat 里面包含着必要的jar包 然后把TOMCAT PATH common lib servlet api jar复制出来 放到 JDK PATH jre lib ext下面 如果不行就重启一下项目
  • 区块链都记录了哪些信息?

    区块如何连接成区块链 之前的文章里又说到区块链 想要知道区块链上的信息首先需要了解一下什么是区块链 区块链其实是一串使用密码学算法产生的区块连接而成 每一个区块上写满了交易记录 区块按顺序相连形成链状结构 就像世界上的电脑一样 电脑每一台电
  • 十四、内置模块path、邂逅Webpack和打包过程、css-loader

    一 内置模块path 1 path介绍 2 path常见的API 这里重点讲一下path resolve 看上面的例子 从右往左开始解析 所以一开始解析的就是 abc txt 这个时候就会把它当成一个绝对路径了 为什么 因为看到斜杠 默认就
  • httpclient工具类

    import java io IOException import java net URI import java util ArrayList import java util List import java util Map imp
  • Channel-wise Knowledge Distillation for Dense Prediction阅读笔记

    Channel wise KD阅读笔记 一 Title 二 Summary 三 Research Object 四 Problem Statement 五 Method 5 1 spatial distillation 5 2 Channe
  • macOS使用 之 读写NTFS格式磁盘

    因为版权问题 macOS并没有开放是支持Windows NTFS 格式硬盘的写入操作 因此对MAC用户使用移动磁盘造成了极大的困扰 下面楼主就来介绍一下mac系统中读取NTFS格式的简单办法 1 使用常见付费软件 如果你土豪级别的人物 不在
  • CHROME扩展开发之·消息传递Message(window.message)

    由于content scripts运行在Web页面的上下文中 属于Web页面的组成部分 而不是Google Chrome扩展程序 但是content scripts又往往需要与Google Chrome扩展程序的其他部分通信以共享数据 这可