Safari扩展无法将标签中的消息调度到IFRAME

时间:2011-03-22 05:27:43

标签: safari-extension

我希望能够从全局页面向其中一个选项卡中的IFRAME内部运行的内容脚本发送消息。我发现Safari扩展API可能有设计疏忽,但不允许这样做。 (与Chrome扩展API相反,后者对扩展程序的各个组件之间的消息传递提供了更全面的支持)。

基本上,我有一个注入所有帧及其IFRAME的inject.js。在inject.js中,我有以下内容用于从全局页面中捕获消息:

 safari.self.addEventListener("message", function(msg) {
    /* do something according to the msg */
  } , false);

在我的全局页面中,我有以下代码广播消息到注入的脚本:

  var broadcast = function(message_name) {
    var ws = safari.application.browserWindows;
    for (var i = 0; i < ws.length; i++) {
      var ts = ws[i].tabs;
      for (var j = 0; j < ts.length; j++) {
        ts[j].page.dispatchMessage(message_name);
      }
    }
  };

我发现消息只会到达注入标签顶部框架的inject.js。消息永远不会到达子IFRAME中注入的消息。

似乎SafariWebPageProxy类仅将消息调度到选项卡中的顶部框架,尽管inject.js脚本已注入到子IFRAME中,并且它们都注册了“message”事件safari.self。

您知道如何将消息发送到子IFRAME中的注入脚本,并且IFRAME来自与顶层不同的域吗?

似乎API中的疏忽是以下缺陷的组合:

(1)通信基本上是基于广播公司的用户。没有像Chrome的chrome.extension.sendRequest API那样基于点对点回调的通信渠道;

(2)如果广播转到所有儿童IFRAME,这将没有问题。但事实并非如此。 SafariWebPageProxy.dispatchMessage()只将消息发送到顶部框架中的inject.js。

有什么建议吗?

2 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。后台只能响应IFRAME消息向IFRAME发送消息。

为了解决这个限制,我使用了轮询:每个IFRAME都会定期向后台页面发送消息,以便为其提供发送消息的选项。

答案 1 :(得分:0)

我知道这真的很老了,但我最近不得不做同样的事情,Safari的情况没有改善。

虽然不理想,但对于safari,你需要依赖window.postMessage()。

顶级注入脚本充当页面上任意和所有iFrame之间的中继代理,接收消息并根据需要将消息传递到后台。虽然它听起来很复杂,但它很可能是在跨源iframe和背景页面之间进行通信的唯一方式。