Chrome 扩展消息传递体系结构
Chrome Extension Messaging Architecture
我最近开始开发我的第一个Chrome扩展程序,主要只是为了看看我是否可以做到,我想知道消息究竟是如何传递的机制。这可能是关于windows.postMessage API的一个更普遍的问题,但我想知道是否有人可以解释控制消息接收和传播的幕后过程。
这是我目前对 w.r.t Chrome 扩展程序的消息传递的理解:
- Javascript有四类:
(1)
与弹出窗口绑定的JS,(2)
在后台运行或作为事件运行的JS,内容脚本中的(3)
JS,以及注入页面(4)
JS。 -
(2) -> (1)
和(3) -> (1)
由runtime.sendMessage()
发送。仅当弹出窗口打开时,才会收到它们。 -
(1) -> (2)
和(3) -> (2)
分别由(3)
和(1)
的runtime.sendMessage()
或tabs.sendMessage()
发送。它们会尽快收到,因为 background/event JS 是持久的(我不太确定这是否是正确的词,因为事件 JS 必须绑定到 eventListeners 中(。 -
(1) -> (3)
和(2) -> (3)
由tabs.sendMessage()
发送。它们会尽快收到,因为只要网页处于活动状态,内容脚本就处于活动状态(因为它存在于并行沙盒中(。 -
(*) -> (4)
和(4) -> (*)
不能由chrome.*
处理安全问题,但(3) -> (4)
和(4) -> (3)
可以由window.postMessage()
处理,因为它们都存在于网页的上下文中。
几件事我特别有疑问 - 第一个是,当然,如果我正确地描述了事情。其他是这些:
runtime.sendMessage()
和tabs.sendMessage()
之间的区别究竟是什么,决定了哪些 JS 实际上可以使用它们?- 消息是如何传递的?调用
*.sendMessage()
或window.postMessage()
时,后台会发生什么?
- Javascript有四类:
(1)
绑定到弹出窗口的JS,(2)
在后台运行或作为事件运行的JS,在内容脚本中(3)
JS,以及注入到页面中的(4)
JS。
(1)
和(2)
实际上是相同的("弹出窗口"也属于"扩展代码" - 请参阅浏览器操作、后台脚本和 chrome 扩展程序的内容脚本之间的通信上下文和方法?
(2) -> (1)
和(3) -> (1)
由runtime.sendMessage()
发送。仅当弹出窗口打开时,才会收到它们。(1) -> (2)
和(3) -> (2)
分别由(3)
和(1)
的runtime.sendMessage()
或tabs.sendMessage()
发送。它们会尽快收到,因为 background/event JS 是持久的(我不太确定这是否是正确的词,因为事件 JS 必须绑定到 eventListeners 中(。
runtime.sendMessage
确实可以通过(1)
、(2)
和(3)
发送。在接收者的角色中,(1)
和(2)
之间没有特殊区别。以下是我对脚本的分类:chrome.runtime.sendMessage
发送的消息通过扩展代码接收,但发件人的帧除外。例如,如果您在后台页面中放置一个<iframe>
并从后台页面调用chrome.runtime.sendMessage
,则将在该帧中触发chrome.runtime.onMessage
。
时,只有在等待事件页面加载后才会调度消息事件。
(1) -> (3)
和(2) -> (3)
由tabs.sendMessage()
发送。它们会尽快收到,因为只要网页处于活动状态,内容脚本就处于活动状态(因为它存在于并行沙盒中(。
只要您拥有有效的选项卡 ID,chrome.tabs.sendMessage
就有意义。由于后台页面没有选项卡 ID,因此无法使用 tabs.sendMessage
向后台页面发送消息。内容脚本、选项卡中的扩展页面、选项卡中的扩展框架都可以接收由 chrome.tabs.sendMessage
发送的消息,因为它们是选项卡的一部分。
(*) -> (4)
和(4) -> (*)
不能由chrome.*
处理安全问题,但(3) -> (4)
和(4) -> (3)
可以由window.postMessage()
处理,因为它们都存在于网页的上下文中。
(4) -> (1,2)
(网页到扩展代码(可以通过externally_connectable实现。
(4) -> (4)
也可以使用 window.postMessage
,但不能直接使用 *.sendMessage
(因为这不包括发送者(。
runtime.sendMessage()
和tabs.sendMessage()
之间的区别究竟是什么,决定了哪些JS实际上可以使用它们?
tabs.sendMessage
只能在选项卡 API 可用时使用,以向选项卡发送消息,而内容脚本也可以使用runtime.sendMessage
。
简而言之,使用 tabs.sendMessage
将消息发送到选项卡,使用 runtime.sendMessage
将消息发送到扩展的其他部分。
- 消息是如何传递的?调用
*.sendMessage()
或window.postMessage()
时,后台会发生什么?
window.postMessage
只有一个接收器,即message
事件只调用一次。*.sendMessage
有零个或多个接收器(如果使用tabs.sendMessage
,则可以通过设置frameId
参数将其限制为一个(,因此可以多次调用chrome.runtime.onMessage
(每帧一次(。如果不小心,可能会通过
window.postMessage
意外将信息泄露给不受信任的脚本。确保在两个方向(从网页到网页(上验证所有消息 - 有关更多信息,请参阅 MDN 上的 Window.postMessage#安全问题文章。*.sendMessage
仅在扩展中传递消息,因此通常是安全的。*.sendMessage
消息都是 JSON 序列化的,这比 postMessage 使用的结构化克隆算法受到的限制要大得多。*.sendMessage
始终需要至少两条 IPC 消息(发送到浏览器进程,浏览器进程到每个接收方(。postMessage
可以更有效地处理,因为消息是在同一渲染器进程中处理的。
这是一个内部实现细节,不保证将来成立。在实践中,这意味着如果您发送大量数据并分析性能,那么您很可能会观察到*.sendMessage
问题多于window.postMessage
问题(对于单方面的基准测试,请参阅例如,对于内容脚本和 Chrome 扩展程序的背景页面之间的消息传递,是否有 32 字节或 64Bytes 这样的大小限制?*.sendMessage(any message, optional function responseCallback)
在内部实现为等效于调用chrome.runtime.connect
(或chrome.tabs.connect
(,使用port.onMessage.addListener
注册responseCallback
,然后断开端口连接(如果未设置回调,则立即断开连接,否则仅在调用回调后(。window.postMessage
对消息进行排队。队列不会立即耗尽,但消息事件会"尽快"调度。
- 为什么我得到Chrome本机消息“;找不到指定的本机消息传递主机&”;
- 消息传递系统 jquery 发送jQuery514109241_1210239812938当我在消息中放入:))时
- 与您的操作系统或体系结构不兼容:fsevents@1.0.11.
- 在Flux体系结构中,如何管理存储相同类型数据的存储
- 有没有一种简单的转换方法可以将chrome消息传递转换为safari消息传递语法
- 具有http服务器、websocket和express的体系结构
- 消息传递接收端
- 改进插件体系结构的实现
- 基本的谷歌chrome扩展消息传递不起作用
- Chrome 扩展消息传递体系结构
- 为什么我无法将此消息传递到选项卡中运行的所有帧
- Chrome扩展消息传递:未发送响应
- 为什么在定义回调/侦听器函数(异步消息传递,port.on)后没有立即设置全局变量
- Chrome 消息传递.未捕获错误:连接到扩展时出错
- Web应用程序的体系结构/设计,对另一台服务器进行了大量Ajax调用
- RESTful Web 应用程序中的客户端服务器体系结构
- 基于 AJAX 的聊天的数据库体系结构
- Socket.io 向某些套接字(体系结构)发出消息
- 在 MQTT 客户端中“未捕获的引用错误:未定义消息传递”
- 用于第三方 API 调用的 Web 应用体系结构