大家好,我是 dom 哥。这是我关于 Chrome 扩展开发的系列文章,感兴趣的可以 点个小星星

一个复杂的 Chrome 扩展程序通常由 content_scriptsbackgroundaction popupside paneloptions pagedevtools 等部分组成,这些部分所负责的功能各不相同,所处的运行环境各不相同,所能访问的 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,意味着不但可以给自身扩展程序发消息,还能给别的扩展程序发消息,它发送的消息可以被扩展的任一部分接收到,包括 backgroundaction popupside paneloptions pagedevtools 等等,除了 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. 大企业才用的分布式唯一Id,它比GUID好

    支持.Net Core(2.0及以上)与.Net Framework(4.5及以上) 可以部署在Docker, Windows, Linux, Mac. 分布式唯一Id,顾名思义,是指在全世界任何一台 ...

  2. Jmeter获取Websocket多帧消息的实现方法

         由于需要对WebSocket进行压力测试,因此又回归到了JMeter的使用.网络上缺少具体的获取多帧消息的操作,且自己也踩了两个坑,总结一下可行的操作供大家参考.   一.情况说明     ...

  3. 噢耶!字节后端Offer,拿到了

    很多同学反馈多搞点面经,说来就来! 今天分享一位拿到字节跳动实习Offer的面经,没错,Java转Go. 别问我选Java还是选Go,成年人不做选择题.先搞定一个语言,再学第二语言从来不是难事. 无论 ...

  4. Matlab 设计仿真CIC滤波器

    2023.09.26 使用CIC滤波器用于降采样.同样的,CIC滤波器也适用于升采样. 参考连接: [1] Matlab中CIC滤波器的应用_dsp.cicdecimator_张海军2013的博客-C ...

  5. 每天5分钟复习OpenStack(三)

    每天5分钟复习OpenStack(三) 为什么要拉起kvm 虚拟机要熟悉这些操作? 作为一个运维工程师,将来有大量的时间是在制作镜像,镜像的制作就是在kvm虚拟化环境拉起kvm 管理的虚拟机的过程,安 ...

  6. Redis 7.0 源码环境搭建与阅读技巧

    天下武功,无坚不摧,唯快不破!我的名字叫 Redis,全称是 Remote Dictionary Server. 有人说,组 CP,除了要了解她外,还要给机会让她了解你. 那么,作为开发工程师的你,是 ...

  7. CSP 2022 游寄

    Day -2147483648 官网有了通知,但选手注册不知为何坏掉了: 先开坑: Day -大概两个月 注册了,但老师还没给我审核呜呜呜 第一轮 早上 早上起床就直接来机房了,不用跑操欸嘿. 上午 ...

  8. Java文件与IO流

    首先我们要清楚什么是流,正如其名,很形象,流就是像水一样的东西,具有方向性,在java中 ,流大概就是类 接下来,我们要对输入输出流有一个基本认识,什么是输入输出流呢? 输入输出明显需要一个参照,而这 ...

  9. NEFU OJ Problem1356 帽儿山奇怪的棋盘 题解

    帽儿山奇怪的棋盘 题目: Time Limit:1000ms | Memory Limit:65535K Description 军哥来到了帽儿山,发现有两位神人在顶上对弈.棋盘长成下图的模样: 每个 ...

  10. Vue 2.x源码学习:render方法、模板解析和依赖收集

    内容乃本人学习Vue2源码的一点笔记,若有错误还望指正. 源码版本: vue: 2.6 vue-loader: 13.x vue-template-compiler: 2.6 之前的相关学习笔记: 应 ...