大家好,我是 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. 《Python魔法大冒险》009 魔法之语:字符串的奥秘

    随着小鱼和魔法师的深入,他们来到了一个被薄雾笼罩的湖泊.湖中央有一个小岛,岛上有一棵巨大的古树,树上挂满了闪闪发光的果实,每一个果实上都刻着一个字母或符号. 小鱼好奇地问:"这些是什么果实? ...

  2. pygame 入门实例教程 1 - 复古方块赛车游戏

    作者自我介绍:大爽歌, b站小UP主 ,直播编程+红警三 ,python1对1辅导老师 . 本教程步骤明确,过程清晰简明,最终代码量250行上下,适合学习pygame的新手. 项目代码已上传到我的gi ...

  3. Python从0到1丨详解图像锐化的Sobel、Laplacian算子

    本文分享自华为云社区<[Python从零到壹] 五十八.图像增强及运算篇之图像锐化Sobel.Laplacian算子实现边缘检测>,作者: eastmount . 一.Sobel算子 So ...

  4. Go运算操作符全解与实战:编写更高效的代码!

    本文全面探讨了Go语言中的各类运算操作符,从基础的数学和位运算到逻辑和特殊运算符.文章旨在深入解析每一种运算操作符的工作原理.应用场景和注意事项,以帮助开发者编写更高效.健壮和可读的Go代码. 简介 ...

  5. ionic4请求skynet服务器的资源跨域问题

    最近在做一个后台接口, 顺便用ionic4写了个简单的管理后台, 本来skynet管理后台监听的端口是6666, 但是发现chrome默认对一些接口不友善, 虽然可以通过设置启动参数来解决, 但是还是 ...

  6. vue2中使用antv/G6节点内容可滚动的ER图

    先举一个栗子: 效果链接:https://code.juejin.cn/pen/7226264955824930816 如果不会请移步到官网的栗子,请点击查看 狠人话不多,直接给大家上代码: 整体代码 ...

  7. 如何使用Java创建数据透视表并导出为PDF

    摘要:本文由葡萄城技术团队原创并首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 前言 数据透视分析是一种强大的工具,可以帮助我们从大量数据中提取有用信 ...

  8. BGP路由协议学习一

    转载请注明出处: 1.BGP的特点: BGP使用TCP作为其传输层协议(端口号为179),使用触发式路由更新,而不是周期性路由更新. BGP能够承载大批量的路由信息,能够支撑大规模网络. BGP提供了 ...

  9. java值传递机制

    目录 1. 基本数据类型 2. 引用数据类型 3. 总结 1. 基本数据类型 public class ValueTransferTest { public static void main(Stri ...

  10. PTA乙级1049

    不能直接两重循环数据是1e5会超时 这样 #include"bitsdc++.h" using namespace std; const int N=1e5+10; double ...