大家好,我是 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扩展程序是如何进行消息传递的的更多相关文章

  1. 【前端工具】Chrome 扩展程序的开发与发布 -- 手把手教你开发扩展程序

    关于 chrome 扩展的文章,很久之前也写过一篇.清除页面广告?身为前端,自己做一款简易的chrome扩展吧. 本篇文章重在分享一些制作扩展的过程中比较重要的知识及难点. 什么是 chrome 扩展 ...

  2. ----转载----【前端工具】Chrome 扩展程序的开发与发布 -- 手把手教你开发扩展程序

    关于 chrome 扩展的文章,很久之前也写过一篇.清除页面广告?身为前端,自己做一款简易的chrome扩展吧. 本篇文章重在分享一些制作扩展的过程中比较重要的知识及难点. 什么是 chrome 扩展 ...

  3. chrome扩展程序开发

    首先,明确两个概念的区别:chrome扩展程序和Web Apps.具体参考:http://www.chromi.org/archives/10106 本文只讨论chrome扩展程序. 最好的开发教程莫 ...

  4. 编写Chrome扩展程序

    Chrome的扩展程序很多,也很容易入门,可以来简单实现一下 看看,慢慢就能实现出一个扩展程序来 每个扩展程序应用一般会包含: 一个manifest清单文件 html文件 js文件 其他文件等 可以看 ...

  5. Web 开发人员必备的12款 Chrome 扩展程序

    之前已经分享过一些帮助 Web 开发人员和设计师的 Chrome 扩展,这次我们继续展示一组很有用的 Chrome 应用程序.这些免费的 Chrome 应用程序可以简化您的工作流程,为了加快您的工作流 ...

  6. Google Chrome 扩展程序开发

    根据公司的规定,每月八小时,弹性工作制.所以大家平时来的不太准时,如果有事,下班也就早些回去了.所以一个月下来工作时间可能不够,但是公司的考勤日历是这样的: 除了请假和法定节假日外,其他样式显示都是一 ...

  7. 解决高版本 Google Chrome 扩展程序强制停用问题 -摘自网络

    1]前往这里下载你喜欢的语言的组策略模板 后缀为.adm (其他的文件自己看 https://docs.google.com/viewer?a=v&pid=sites&srcid=Y2 ...

  8. 【转】编写Chrome扩展程序

    Chrome的扩展程序很多,也很容易入门,可以来简单实现一下 看看,慢慢就能实现出一个扩展程序来 每个扩展程序应用一般会包含: 一个manifest清单文件 html文件 js文件 其他文件等 可以看 ...

  9. Chrome扩展程序——TabCopy:一键复制网页标题和网址

    Chrome扩展程序——TabCopy:一键复制网页标题和网址 - Erik_ly的博客 - CSDN博客 https://blog.csdn.net/u012318074/article/detai ...

  10. 如何用原生js开发一个Chrome扩展程序

    原文地址:How to Build a Simple Chrome Extension in Vanilla JavaScript 开发一个Chrome扩展程序非常简单,只需要使用原生的js就可以完成 ...

随机推荐

  1. 探索计算机的I/O控制方式:了解DMA控制器的作用与优势

    I/O控制方式 在前面我们已经了解到,每个设备都配备了一个设备控制器.当CPU向设备控制器发送命令并将其存储在寄存器中时,设备控制器会执行相应的操作.然而,尽管设备控制器会更新状态寄存器的状态,但是如 ...

  2. Laf 云开发平台及其实现原理

    Laf 产品介绍 自我介绍 大家好,我是来自 Laf 团队的王子俊,很高兴今天能在这里给大家分享我们 Laf 云开发平台及其实现原理.本来想说一点什么天气之类的话作为开头,但主持人都说完啦,我就不多说 ...

  3. Vue源码学习(六):(支线)渲染函数中with(),call()的使用以及一些思考

    好家伙,   昨天,在学习vue源码的过程中,看到了这个玩意 嘶,看不太懂,研究一下   1.上下文 这段出现vue模板编译的虚拟node部分 export function renderMixin( ...

  4. Solution -「九省联考 2018」IIIDX

    Description Link. 给出一个堆,然后让你填数进去,使得其满足小根堆的性质,并使编号靠前的点的数最大. Solution 考虑贪心,把原数列降序排序,然后因为这个东西是整除分块的形式,所 ...

  5. Three.js中实现一个OBBHelper

    1. 引言 Three.js中,Box3对象指的是AABB式的包围盒,这种包围盒会随物体的旋转而变换大小,精度较差 Three.js中还有OBB对象,这是一种能表现物体主要特征的.不随物体的旋转而变换 ...

  6. 记一次 .NET 某拍摄监控软件 卡死分析

    一:背景 1. 讲故事 今天本来想写一篇 非托管泄露 的生产事故分析,但想着昨天就上了一篇非托管文章,连着写也没什么意思,换个口味吧,刚好前些天有位朋友也找到我,说他们的拍摄监控软件卡死了,让我帮忙分 ...

  7. 记录 Ucharts 的使用

    1.开启 2d 渲染 线上运行开启 canvas2d 可以解决图表显示问题 <qiun-data-charts canvas2d .../> canvasId 可以不传,官方内置生成随机字 ...

  8. 虹科干货 | 什么是Redis数据集成(RDI)?

    大量的应用程序.日益增长的用户规模.不断扩展的技术需求,以及对即时响应的持续追求.想想这些是否正是你在经历的.也许你尝试过自己构建工具来应对这些需求,但是大量的编码和集成工作使你焦头烂额.那你是否知道 ...

  9. 新手面对安卓6.0以上的版本时出现一个关于文件权限检测的问题,报错为:“无法解析符号 'checkSelfPermission'”,解决办法

    [[注意]:这只是笔者在遇到这个问题时的解决方法,如果对您毫无帮助,请自寻他法!!!] 面对新手:在简单做一个音乐播放程序时,如果面对安卓6.0以上的版本,就会出现一个关于文件权限检测的问题,报错为: ...

  10. Redis平台-整合PHP

    1.Redis的相关介绍: 定义: redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合 ...