Chrome扩展程序是如何进行消息传递的
大家好,我是 dom 哥。这是我关于 Chrome 扩展开发的系列文章,感兴趣的可以 点个小星星。
一个复杂的 Chrome 扩展程序通常由 content_scripts
,background
,action popup
,side panel
,options page
,devtools
等部分组成,这些部分所负责的功能各不相同,所处的运行环境各不相同,所能访问的 chrome.*
API 也各不相同,也因此经常需要通信告诉对方需要做什么。
下面是我画的一张图,简单说明各部分关系:
这些花花绿绿的部分各自运行在不同的环境中,往往需要相互通信,Chrome 为我们提供了两种通信方式:
- 一种是一次性请求(one-time requests),一次只能发一条消息,类似于手机发短信,跟 HTTP 请求很像。
- 一种是长期连接(long-lived connections),允许发送多条消息,类似于手机打电话,跟 Websocket 连接很像。
接下来就详细说说这两种通信方式。
一次性请求(one-time requests)
如果要向扩展程序的另一部分发送一条消息,有两个 API 可供调用:
chrome.runtime.sendMessage(extensionId?, message)
chrome.tabs.sendMessage(tabId, message)
从函数签名很容易看出来,一个是向扩展程序的各个部分发消息的,另一个是给某个浏览器的某个页签发消息的。
为什么设计两个 API?这是因为 content_scripts
是一个很独特的存在!
先说说浏览器的的工作原理。
浏览器的每个页签都是单独的线程。每个页签运行在与其他页签或扩展相隔离的独立线程中。如下图所示
我们在每个页签中打开页面。content_scripts
是一个很特殊的存在!作为被注入到页面的脚本,它的生命周期跟随页面。而扩展程序的其他部分,都有自己的生命周期!如果你在各个部分查看它们的 location
,就会发现,只有 content_scripts
的 origin 是页面的 url 一样,而其它部分的 location.origin 都是 chrome://your-extention-id
。
知道了 content_scripts
的特殊性后,那么这两个 API 就很好理解了。
chrome.runtime.sendMessage()
是给扩展程序发消息的,它的第一个参数是一个可选的 extensionId,意味着不但可以给自身扩展程序发消息,还能给别的扩展程序发消息,它发送的消息可以被扩展的任一部分接收到,包括 background
,action popup
,side panel
,options page
,devtools
等等,除了 content_scripts
!!!
那么想给 content_scripts
发送消息怎么办呢???
chrome.tabs.sendMessage()
就是专门用来给 content_scripts
发消息的!值得注意的是,想要给 content_scripts
发消息需要指定 tabId,也就是需要指明给哪个页签下的页面的 content_scripts
发消息。这个设计很好,因为每个页签的页面都运行了一份 content_scripts
,这就避免了无关的页面接收到消息。
发送消息搞定啦,有方法发送就得有方法接收才行啊。
接收消息的方法只有一个 API:
chrome.runtime.onMessage.addListener(
(message, sender, sendResponse) => boolean | undefined
)
在扩展程序的任意部分(包括 content_scripts
)都是用这个接收消息。这很方便。
长期连接(long-lived connections)
长期链接的 API 和一次性消息的 API 是相互对应的。
要创建一个可重复使用的长期消息传递通道,有两个 API 可以调用:
chrome.runtime.connect(extensionId?, connectInfo?): Port
chrome.tabs.connect(tabId, connectInfo?): Port
这两个 API 的设计和一次性消息的一样。
chrome.runtime.connect()
用于和扩展程序的任一部分建立消息通道,除了 content_scripts
!!!
而 chrome.tabs.connect()
是专门用来和 content_scripts
建立消息通道哒!
chrome.{runtime,tabs}.connect()
返回的是一个 Port 对象。Port 就是被设计用来在扩展程序的不同部分之间进行双向通信的一个接口。
觉得不错可以 点个小星星 支持一下哦
Chrome扩展程序是如何进行消息传递的的更多相关文章
- 【前端工具】Chrome 扩展程序的开发与发布 -- 手把手教你开发扩展程序
关于 chrome 扩展的文章,很久之前也写过一篇.清除页面广告?身为前端,自己做一款简易的chrome扩展吧. 本篇文章重在分享一些制作扩展的过程中比较重要的知识及难点. 什么是 chrome 扩展 ...
- ----转载----【前端工具】Chrome 扩展程序的开发与发布 -- 手把手教你开发扩展程序
关于 chrome 扩展的文章,很久之前也写过一篇.清除页面广告?身为前端,自己做一款简易的chrome扩展吧. 本篇文章重在分享一些制作扩展的过程中比较重要的知识及难点. 什么是 chrome 扩展 ...
- chrome扩展程序开发
首先,明确两个概念的区别:chrome扩展程序和Web Apps.具体参考:http://www.chromi.org/archives/10106 本文只讨论chrome扩展程序. 最好的开发教程莫 ...
- 编写Chrome扩展程序
Chrome的扩展程序很多,也很容易入门,可以来简单实现一下 看看,慢慢就能实现出一个扩展程序来 每个扩展程序应用一般会包含: 一个manifest清单文件 html文件 js文件 其他文件等 可以看 ...
- Web 开发人员必备的12款 Chrome 扩展程序
之前已经分享过一些帮助 Web 开发人员和设计师的 Chrome 扩展,这次我们继续展示一组很有用的 Chrome 应用程序.这些免费的 Chrome 应用程序可以简化您的工作流程,为了加快您的工作流 ...
- Google Chrome 扩展程序开发
根据公司的规定,每月八小时,弹性工作制.所以大家平时来的不太准时,如果有事,下班也就早些回去了.所以一个月下来工作时间可能不够,但是公司的考勤日历是这样的: 除了请假和法定节假日外,其他样式显示都是一 ...
- 解决高版本 Google Chrome 扩展程序强制停用问题 -摘自网络
1]前往这里下载你喜欢的语言的组策略模板 后缀为.adm (其他的文件自己看 https://docs.google.com/viewer?a=v&pid=sites&srcid=Y2 ...
- 【转】编写Chrome扩展程序
Chrome的扩展程序很多,也很容易入门,可以来简单实现一下 看看,慢慢就能实现出一个扩展程序来 每个扩展程序应用一般会包含: 一个manifest清单文件 html文件 js文件 其他文件等 可以看 ...
- Chrome扩展程序——TabCopy:一键复制网页标题和网址
Chrome扩展程序——TabCopy:一键复制网页标题和网址 - Erik_ly的博客 - CSDN博客 https://blog.csdn.net/u012318074/article/detai ...
- 如何用原生js开发一个Chrome扩展程序
原文地址:How to Build a Simple Chrome Extension in Vanilla JavaScript 开发一个Chrome扩展程序非常简单,只需要使用原生的js就可以完成 ...
随机推荐
- WPF学习 - 动画基础(1)
1. WPF中的动画(Animation),是一种属性动画.技术上来说,它是让属性从一个值,变化到另一个值的过程.因此,有两条重要的特性: 1.1 只能为依赖属性应用动画(因为第二条特性). 1.2 ...
- 使用flask开发web应用
Flask环境搭建 要开发flash应用,我们需要做一些准备工作 我写了个初始化的脚本 Pip_init.sh来安装初始工作 可以到我的git上去下载该脚本进行初始化安装 要启动flask应用,我们需 ...
- 搭建Minio分布式服务
本文主要介绍Minio的分布式环境搭建,安装比较简单,因博主只有一台window,所以使用VM虚拟机搭建的. 搭建前可以先了解下minio: 1.官方文档:https://docs.min.io/cn ...
- Go运算操作符全解与实战:编写更高效的代码!
本文全面探讨了Go语言中的各类运算操作符,从基础的数学和位运算到逻辑和特殊运算符.文章旨在深入解析每一种运算操作符的工作原理.应用场景和注意事项,以帮助开发者编写更高效.健壮和可读的Go代码. 简介 ...
- 2017-A1
#include <iostream> #include <string> using namespace std; int main(){ string s; cin> ...
- webgl centroid质心插值的一点理解
质心插值说的是什么 2023.10.04再次review这个细节点: https://www.opengl.org/pipeline/article/vol003_6/ https://github. ...
- 08-03_阅读flask上下文前夕补充、flask请求上下文、数据库连接池
文章目录 阅读flask上下文前夕补充 01 偏函数 02 __add__的使用 03 chain函数 2 flask请求上下文 1 首先分析请求上下文对象(ctx)创立 2 把请求对象(ctx)添加 ...
- .netCore 图形验证码,非System.Drawing.Common
netcore需要跨平台,说白点就是放在windows服务器要能用,放在linux服务器上也能用,甚至macos上. 很多时候需要使用到图形验证码,这就有问题了. 旧方案1.引入包 <Packa ...
- 每天5分钟复习OpenStack(四) virsh 常用命令
在上一章节中,我们拉起了第一台虚拟机,但是执行virsh shutdown 关机是无法关机的,需要使用virsh destroy 强制断电的命令来关机.为什么会这样了? 这里我们介绍下 QGA的概念 ...
- CodeTON Round 4 (Div. 1 + Div. 2)C
C. Make It Permutation 我们希望尽可能少地进行操作可以使代价最小,我们如果要排列的话,那些重复的元素我们无论如何都要进行删除的,所以我们可以先把去重的代价计算出来,然后依次枚举排 ...