开发者

Safari extension unable to dispatchMessage to IFRAMEs in tab

I want to be able to dispatch a message from the global page to the content script running inside an IFRAME in one of the tabs. I found that the Safari extension API may have a design oversight that does not a开发者_开发知识库llow this. (As opposed to the Chrome extension API, which has more comprehensive support for messaging between various components of an extension).

Basically, I have an injected.js that is injected to all frames and their IFRAMEs. In injected.js, I have the following for catching messages from the global page:

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

In my global page, I have the following code that broadcasts messages to the injected scripts:

  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);
      }
    }
  };

What I found is that the messages only reach the injected.js injected into the top frames of the tabs. The messages never reach those that are injected in the child IFRAMEs.

It appears that the SafariWebPageProxy class only dispatches messages to the top frame in the tab, in spite of the fact that the injected.js script is injected into the child IFRAMEs, and that they all register for the "message" event on safari.self.

Do you know how I can get the messages to the injected script in a child IFRAME, and that the IFRAME is from a different domain vs the top frame?

It appears that the oversight in the API is as a combination of the following flaws:

(1) communications are basically broadcaster-subscriber based. There is no point-to-point callback-based communication channel like Chrome's chrome.extension.sendRequest API;

(2) this would have been fine if the broadcast goes to all child IFRAMEs. However, that is not the case. SafariWebPageProxy.dispatchMessage() only send the message the to injected.js in the top frame.

Any suggestion?


I ran to the same issue. Background can send a message to an IFRAME only in response to an IFRAME message.

To get around the limitation, I've used polling: each IFRAME is sending messages regularly to the background page to give it an option to send a message.


I know this is really old, but I recently had to do the same thing and the situation with Safari has not improved.

Although not ideal, for safari you need to rely on window.postMessage().

The top level injected script acts as a relaying agent between any and all iFrames on the page, taking in messages and passing them on to the background as needed. As complicated as that it sounds, it's quite likely the only way of making communication between a cross-origin iframe and the background page possible.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜