Chrome 插件各模块之间的消息传递

2024-03-27 08:52

本文主要是介绍Chrome 插件各模块之间的消息传递,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Chrome 插件各模块之间的消息传递

一、消息传递

1. 消息传递分类

  • Chrome 插件的 ActionBackgroundcontent_script 三个模块之间的信息传输
  • 插件和插件之间的信息传输
  • 网页向插件进行信息传输
  • 与原生应用进行消息传递

2. 消息传递 API

  • runtime API
    • runtime.sendMessage()
    • runtime.onMessage.addListener()
    • runtime.connect()
    • runtime.onConnect.addListener()
    • runtime.onMessageExternal
    • runtime.onConnectExternal
  • tabs API
    • tabs.sendMessage()
    • tabs.connect()

3. 消息传递 API 类别

  • 一次性请求
    • sendMessage
  • 长期连接(允许发送多条消息)
    • connect

二、chrome 字段展示

1. Action chrome 字段包含内容

  1. Action chrome 内容
    共 13 个
    'loadTimes', 'csi', 'action', 'dom', 'extension', 'i18n', 'management', 'permissions', 'runtime', 'scripting', 'storage', 'tabs', 'windows'

在这里插入图片描述

  1. Chrome.runtime 内容
    共 35 个:

'id','onRestartRequired','onUserScriptMessage','onMessageExternal','onMessage','onUserScriptConnect','onConnectExternal','onConnect','onBrowserUpdateAvailable','onUpdateAvailable','onSuspendCanceled','onSuspend','onInstalled','onStartup','connect','getBackgroundPage','getContexts','getManifest','getPackageDirectoryEntry','getPlatformInfo','getURL','openOptionsPage','reload','requestUpdateCheck','restart','restartAfterDelay','sendMessage','setUninstallURL','ContextType','OnInstalledReason','OnRestartRequiredReason','PlatformArch','PlatformNaclArch','PlatformOs','RequestUpdateCheckStatus'

在这里插入图片描述

2. Background chrome 字段包含内容

  1. Background chrome 内容

共 13 个
'loadTimes', 'csi', 'action', 'dom', 'extension', 'i18n', 'management', 'permissions', 'runtime', 'scripting', 'storage', 'tabs', 'windows'

在这里插入图片描述

  1. Chrome.runtime 内容
    共 34 个

'id', 'onRestartRequired', 'onUserScriptMessage', 'onMessageExternal', 'onMessage', 'onUserScriptConnect', 'onConnectExternal', 'onConnect', 'onBrowserUpdateAvailable', 'onUpdateAvailable', 'onSuspendCanceled', 'onSuspend', 'onInstalled', 'onStartup', 'connect', 'getContexts', 'getManifest', 'getPlatformInfo', 'getURL', 'openOptionsPage', 'reload', 'requestUpdateCheck', 'restart', 'restartAfterDelay', 'sendMessage', 'setUninstallURL', 'ContextType', 'OnInstalledReason', 'OnRestartRequiredReason', 'PlatformArch', 'PlatformNaclArch', 'PlatformOs', 'RequestUpdateCheckStatus', 'getBackgroundClient'

在这里插入图片描述

3. Content script chrome 内容

  1. Content script chrome 内容

共 7 个
'csi','dom','extension','i18n','loadTimes','runtime','storage'
在这里插入图片描述

  1. Chrome.runtime 内容

共 14 个
'id', 'onMessage', 'onConnect', 'ContextType', 'OnInstalledReason', 'OnRestartRequiredReason', 'PlatformArch', 'PlatformNaclArch', 'PlatformOs', 'RequestUpdateCheckStatus','connect','getManifest','getURL','sendMessage'

在这里插入图片描述

通过上图可以看出不同的模块中的 chrome 字段包含的内容不一样,不同的 runtime 字段包含的内容也不一样,但是都有 sendMessage 可以进行消息发送

三、消息传递示例

1. Action(popup)background(service worker) 之间的通信

1.1. 在 popup 中的 index.js 中添加点击事件,进行消息发送
  • popup 中使用 chrome.runtime.sendMessage 进行消息发送
plugin_search_but.onclick = function () {chrome.runtime.sendMessage({action: 'fromPopup',message: 'Hello from Popup!'});
}
1.2. 在 service_worker.js 中接收消息
  • service_worker 中使用 chrome.runtime.onMessage.addListener 进行消息监听,通过 .action 来判断来源
chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {if (message.action === 'fromPopup') {chrome.notifications.create({type: "basic",title: "Notifications Title",message: "Notifications message to display",iconUrl: "../icons/icon.png"},(notificationId) => {console.log('notificationId-->', notificationId)});}
});
1.3. 消息中心消息弹出

在这里插入图片描述

2. Content scriptbackground(Service Worker) 通信

2.1. 在 content_scripts 中添加点击事件进行消息发送
  • content_scripts 中使用 chrome.runtime.sendMessage 进行消息发送
$('#contentBut').click(async (e) => {// 发送消息chrome.runtime.sendMessage({action: "fromContent"});
})
2.2. 在 Service_worker.js 里面进行消息接收
  • service_worker 中使用 chrome.runtime.onMessage.addListener 进行消息监听,通过 .action 来判断来源
chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {if (message.action === 'fromContent') {chrome.notifications.create({type: "basic",title: "Notifications Title",message: "Notifications message to display",iconUrl: "../icons/icon.png"},(notificationId) => {console.log('notificationId-->', notificationId)});}
});
2.3. 消息中心弹出

在这里插入图片描述

3. Action(popup)content 通信

因为 content 是注入页面的脚本,所以和 content 通信,需要获取当前 tab 信息

1. 获取当前 tab 信息
// 以豆瓣举例
const [tab] = await chrome.tabs.query({url: ["https://movie.douban.com/*"],active: true,currentWindow: true
});
console.log('tab', tab)

在这里插入图片描述

2. popupcontent 发送消息,content 接收消息
2.1 popup 中使用 chrome.tabs.sendMessage 发送消息,content 中使用 chrome.runtime.onMessage.addListener 接收消息
  1. popup 代码
plugin_search_but.onclick = async function () {const [tab] = await chrome.tabs.query({url: ["https://movie.douban.com/*"],active: true,currentWindow: true});console.log('tab', tab)if (tab) {// 使用 chrome.tabs.sendMessage 发送消息chrome.tabs.sendMessage(tab.id, {action: 'fromPopup2Content'})}
}
  1. content 使用 chrome.runtime.onMessage.addListener 进行消息监听
chrome.runtime.onMessage.addListener((e) => {console.log('e', e)
})
  1. 控制台输出

在这里插入图片描述

2.2 popup 中使用 chrome.tabs.connect 发送消息,content 使用 chrome.runtime.onConnect.addListener 来接收消息
  1. popup 代码
plugin_search_but.onclick = async function () {const [tab] = await chrome.tabs.query({url: ["https://movie.douban.com/*"],active: true,currentWindow: true});console.log('tab', tab)if (tab) {const connect = chrome.tabs.connect(tab.id, {name: 'fromPopup2Content'});console.log('connect', connect)connect.postMessage('这里是弹出框页面,你是谁?')connect.onMessage.addListener((mess) => {console.log(mess)})}
}
  1. content 中使用 chrome.runtime.onConnect.addListener 进行消息监听
chrome.runtime.onConnect.addListener((res) => {console.log('contentjs中的 chrome.runtime.onConnect:',res)if (res.name === 'fromPopup2Content') {res.onMessage.addListener(mess => {console.log('contentjs中的 res.onMessage.addListener:', mess)res.postMessage('哈哈哈,我是contentjs')})}
})
  1. 日志输出

content 页面日志输出

在这里插入图片描述

popup 页面日志输出

在这里插入图片描述

4. 与其他插件进行通信

4.1. 如需监听传入请求和来自其他插件的连接,需使用 runtime.onMessageExternalruntime.onConnectExternal 方法
// 一次性请求
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {if (sender.id === blocklistedExtension)return;  // don't allow this extension accesselse 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.});
});
4.2. 要向其他插件发送消息,需要其他插件的 ID
// 插件 ID
var laserExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";// 一次性请求
chrome.runtime.sendMessage(laserExtensionId, {getTargetData: true},function(response) {if (targetInRange(response.targetData))chrome.runtime.sendMessage(laserExtensionId, {activateLasers: true});}
);// 长期请求
var port = chrome.runtime.connect(laserExtensionId);
port.postMessage(...);

5. 网页给插件发送消息

插件也可以接收和响应来自其他网页的消息,但无法向网页发送消息

5.1. 插件配置
  • 如需从网页向插件发送消息,需要在 manifest.json 中使用 "externally_connectable" 指定要与哪些网站通信
  • 这会将 Messaging API 公开给指定的网址格式匹配的任何页面
  • 网址格式必须包含至少一个“二级网域”;也就是说,不支持 *、*.com、*.co.uk 和 *.appspot.com 等主机名格式
  • 也可以使用 <all_urls> 访问所有网域
{"externally_connectable": {"matches": ["https://*.douban.com/*"]}
}
5.2. 网页向插件发送消息
  • 使用 runtime.sendMessage()runtime.connect() API 向特定应用或插件发送消息
  • 需要指定插件 ID
5.2.1 Web 页面
  • 使用 runtime.sendMessage()runtime.connect() API 向特定应用或插件发送消息
var editorExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";chrome.runtime.sendMessage(editorExtensionId, {openUrlInEditor: url},
function(response) {if (!response.success)handleError(url);
});
5.2.2 service-worker.js 页面
  • 使用 runtime.onMessageExternalruntime.onConnectExternal API 监听网页中的消息
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {if (sender.url === blocklistedWebsite) // 当 URL 等于设置的 blocklistedWebsite 时return;if (request.openUrlInEditor)openUrl(request.openUrlInEditor);
});

6. 原生消息传递

插件可以使用与其他消息传递 API 类似的 API 与原生应用交换消息,支持此功能的原生应用必须注册可与插件进行通信的原生消息传递主机。Chrome 会在单独的进程中启动主机,并使用标准输入和标准输出流与其进行通信

6.1. 原生消息传递主机配置文件

如需注册原生消息传递主机,应用必须保存一个定义原生消息传递主机配置的文件,示例如下:

{"name": "com.my_company.my_application","description": "My Application","path": "C:\\Program Files\\My Application\\chrome_native_messaging_host.exe","type": "stdio","allowed_origins": ["chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"]
}

JSON 文件必需包含以下字段

  • name:原生消息传递主机的名称,客户端将此字符串传递给 runtime.connectNative()runtime.sendNativeMessage()
    • 此名称只能包含小写字母数字字符下划线和英文句号
  • description:应用说明
  • path:二进制文件的路径
  • type:接口类型
    • stdio
    • stdin
    • stdout
  • allowed_origins:插件 ID 列表
6.2. 连接到原生应用

向原生应用收发消息与跨插件消息传递非常相似。主要区别在于,使用的是 runtime.connectNative() 而非 runtime.connect(),使用的是 runtime.sendNativeMessage() 而不是 runtime.sendMessage()

需要在权限中声明 nativeMessaging 权限

service_worker.js 中进行消息监听和消息发送

  1. 使用 connectNative
var port = chrome.runtime.connectNative('com.my_company.my_application');
port.onMessage.addListener(function (msg) {console.log('Received' + msg);
});
port.onDisconnect.addListener(function () {console.log('Disconnected');
});
port.postMessage({text: 'Hello, my_application'});
  1. 使用 sendNativeMessage
chrome.runtime.sendNativeMessage('com.my_company.my_application',{text: 'Hello'},function (response) {console.log('Received ' + response);}
);

这篇关于Chrome 插件各模块之间的消息传递的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/851572

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

day-51 合并零之间的节点

思路 直接遍历链表即可,遇到val=0跳过,val非零则加在一起,最后返回即可 解题过程 返回链表可以有头结点,方便插入,返回head.next Code /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}*

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

zeroclipboard 粘贴板的应用示例, 兼容 Chrome、IE等多浏览器

zeroclipboard单个复制按钮和多个复制按钮的实现方法 最近网站改版想让复制代码功能在多个浏览器上都可以实现,最近看网上不少说我们的代码复制功能不好用的,我们最近将会增加代码高亮等功能,希望大家多多支持我们 zeroclipboard是一个跨浏览器的库类 它利用 Flash 进行复制,所以只要浏览器装有 Flash 就可以运行,而且比 IE 的

Maven(插件配置和生命周期的绑定)

1.这篇文章很好,介绍的maven插件的。 2.maven的source插件为例,可以把源代码打成包。 Goals Overview就可以查看该插件下面所有的目标。 这里我们要使用的是source:jar-no-fork。 3.查看source插件的example,然后配置到riil-collect.xml中。  <build>   <plugins>    <pl

Jenkins构建Maven聚合工程,指定构建子模块

一、设置单独编译构建子模块 配置: 1、Root POM指向父pom.xml 2、Goals and options指定构建模块的参数: mvn -pl project1/project1-son -am clean package 单独构建project1-son项目以及它所依赖的其它项目。 说明: mvn clean package -pl 父级模块名/子模块名 -am参数

jenkins 插件执行shell命令时,提示“Command not found”处理方法

首先提示找不到“Command not found,可能我们第一反应是查看目标机器是否已支持该命令,不过如果相信能找到这里来的朋友估计遇到的跟我一样,其实目标机器是没有问题的通过一些远程工具执行shell命令是可以执行。奇怪的就是通过jenkinsSSH插件无法执行,经一番折腾各种搜索发现是jenkins没有加载/etc/profile导致。 【解决办法】: 需要在jenkins调用shell脚

Jenkins 插件 地址证书报错问题解决思路

问题提示摘要: SunCertPathBuilderException: unable to find valid certification path to requested target...... 网上很多的解决方式是更新站点的地址,我这里修改了一个日本的地址(清华镜像也好),其实发现是解决不了上述的报错问题的,其实,最终拉去插件的时候,会提示证书的问题,几经周折找到了其中一遍博文

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类