Chrome扩展消息传递架构

时间:2016-04-02 08:36:40

标签: javascript google-chrome google-chrome-extension sendmessage

我最近开始开发我的第一个Chrome扩展程序,主要是为了看看我能不能做到这一点,而且我想知道消息传递方式背后的机制。这可能会成为关于windows.postMessage API的更普遍的问题,但我想知道是否有人可以解释控制消息接收和传播的幕后流程。

这是我目前对w.r.t Chrome扩展程序的消息的理解:

  • 有四类Javascript:(1) JS绑定到弹出窗口,(2) JS在后台运行或作为事件,(3) JS在内容脚本中,{{1 JS注入页面。
  • {li> (4)(2) -> (1)(3) -> (1)发送。它们仅在弹出窗口打开时才会收到。
  • runtime.sendMessage()(1) -> (2)分别由(3) -> (2)runtime.sendMessage()tabs.sendMessage()(3)发送。他们很快就收到了,因为背景/事件JS是持久的(我不太确定这是否是正确的词,因为事件JS必须绑定到eventListeners)。
  • {li> (1)(1) -> (3)(2) -> (3)发送。他们已经收到ASAP,因为只要网页是(因为它存在于并行沙箱中),内容脚本就是活动的。 {li> tabs.sendMessage()(*) -> (4)无法由(4) -> (*)处理安全问题,但chrome.*(3) -> (4)可由{{1}处理因为它们都存在于网页的上下文中。

我有一些具体问题 - 第一个是,当然,如果我甚至正确地描述了事情。其他是这些:

  • (4) -> (3)window.postMessage()之间的区别是什么决定哪些JS可以实际使用它们?
  • 如何传递消息?调用runtime.sendMessage()tabs.sendMessage()后,后台会发生什么?

1 个答案:

答案 0 :(得分:2)

  
      
  • 有四类Javascript:(1) JS绑定到弹出窗口,(2) JS在后台运行或作为事件,(3) JS在内容脚本中,{{1 JS注入页面。
  •   

(4)(1)实际上是相同的(" popup"也属于"扩展代码" - 请参阅Contexts and methods for communication between the browser action, background scripts, and content scripts of chrome extensions?)。

  
      {li> (2)(2) -> (1)(3) -> (1)发送。它们仅在弹出窗口打开时才会收到。   
  • runtime.sendMessage()(1) -> (2)分别由(3) -> (2)runtime.sendMessage()tabs.sendMessage()(3)发送。他们很快就收到了,因为背景/事件JS是持久的(我不太确定这是否是正确的词,因为事件JS必须绑定到eventListeners)。
  •   

(1)确实可以由runtime.sendMessage(1)(2)发送。在接收者的角色中,(3)(1)之间没有特别的区别。以下是my classification of scripts的来源:(2)发送的邮件由扩展程序代码接收,发件人的框架除外。例如,如果您在后台页面中放置chrome.runtime.sendMessage并从后台页面调用<iframe>,则会在该帧中触发chrome.runtime.sendMessage

当使用event pages时,仅在等待加载事件页面后才调度消息事件。

  
      {li> chrome.runtime.onMessage(1) -> (3)(2) -> (3)发送。他们已经收到ASAP,因为只要网页是(因为它存在于并行沙箱中),内容脚本就是活动的。   
只要您拥有有效的标签ID,

tabs.sendMessage()就有意义。由于后台页面没有标签ID,因此无法使用chrome.tabs.sendMessage向背景页面发送消息。内容脚本,标签中的扩展程序页,标签中的扩展程序框都可以接收tabs.sendMessage发送的邮件,因为它们是标签的一部分。

  
      {li> chrome.tabs.sendMessage(*) -> (4)无法由(4) -> (*)处理安全问题,但chrome.*(3) -> (4)可由{{1}处理因为它们都存在于网页的上下文中。   

(4) -> (3)(扩展代码的网页)可以通过externally_connectable

window.postMessage()也可以使用(4) -> (1,2),但不能直接使用(4) -> (4)(因为这不包括发件人)。

  
      
  • window.postMessage*.sendMessage之间的区别是什么决定哪些JS可以实际使用它们?
  •   

runtime.sendMessage()只能在标签API可用时使用,才能向标签发送消息,而内容脚本也可以使用tabs.sendMessage()

简而言之,使用tabs.sendMessage向选项卡发送消息,使用runtime.sendMessage将消息发送到您的扩展程序的其他部分。

  
      
  • 如何传递消息?调用tabs.sendMessageruntime.sendMessage后,后台会发生什么?
  •   
  • *.sendMessage()只有一个接收器,即message event只被调用一次。 window.postMessage()有零个或多个接收者(如果您使用tabs.sendMessage,则可以通过设置window.postMessage参数将其限制为一个),因此可以多次调用chrome.runtime.onMessage(每帧一次)。

  • 如果您不小心,可能会通过*.sendMessage意外地将信息泄露给不受信任的脚本。确保您在两个方向(从网页进出)验证所有邮件 - 有关详细信息,请参阅Window.postMessage#Security concerns article on MDNframeId仅在您的扩展程序中传递消息,因此通常是安全的。

  • window.postMessage条消息为JSON-serialized,比postMessage使用的structured cloning algorithm要严格得多。

  • *.sendMessage始终需要至少两个IPC messages(发送者到浏览器进程,浏览器进程到每个接收者)。由于消息是在同一个渲染器进程中处理的,因此可以更有效地处理*.sendMessage 这是一个内部实施细节,并且不保证将来会保留。在实践中,它意味着如果您发送大量数据并分析性能,那么您很可能会发现*.sendMessagepostMessage更多的问题(对于单侧基准,请参阅例如Is there a size limit like 32bytes or 64Bytes? for message passing between content scripts and background pages for chrome extensions?)。

  • *.sendMessage在内部实现为等同于的东西 调用chrome.runtime.connect(或chrome.tabs.connect),使用window.postMessage注册*.sendMessage(any message, optional function responseCallback),然后断开端口(如果没有设置回调则立即断开,否则只有在调用回调之后)。< / p>

    responseCallback queues a message。队列不会立即耗尽,但会尽快发送消息事件&#34;