如何使用postMessage从嵌套的iframe到根文档进行通信

how to use postMessage to communicate from nested iFrames to the root document?

本文关键字:文档 通信 iframe postMessage 何使用 嵌套      更新时间:2023-09-26

我正在开发一个插件,它必须管理相当复杂的页面嵌套iframes,像这样:

page.html
<body>
 <iframe A>
  <iframe B>
   <div bla></div>
  </iframe>
 </iframe>
 <iframe C>
   <div foo></div>
 </iframe>
</body>

插件将在多个实例中运行(一个在主页上,一个为每个iFrame)。为了通知iFrame关于root实例,我在生成iFrame时将根URL作为参数传递,如下所示:

 ...
 newHTML = document.createElement("iframe");
 newHTML.setAttribute("src", options.src + "?" + priv.encodeURI(rootPath));

那么iFrame将被加载一个URL,像这样:

 http://www.path/to/iFrame.html?base=...encodeURI(window.location.href.of.root)

我的问题是,我需要postMessage从一个嵌套的iFrame到根,我不能让它工作。下面是我正在做的:

// sending a message
var adressArray = window.location.href.split("?");
options.src = options.src || adressArray[0];
window.postMessage(options, options.src);
// receiving
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event) {
  console.log(event.data);
  console.log(event.origin);
  console.log(window);
}

我的问题是,调用和侦听器都在同一个插件中,但应该在插件的不同实例中侦听。因此,postmessage将由frame B实例触发,并且page.html实例上的侦听器应该检测到该消息。

我认为targetOrigin属性是指定目的地的postMessage应该被发送到哪里。相反,我最终发送了我的张贴iFrame (B)的URL,这是由父iFrame (A)记录的,而不是page.html实例侦听它。

问题:
是否有可能"跨"两个(或任意数量的)父节点发送postMessage,而不需要人为地将其"冒泡"到树中?说iFrame的实例B想说"你好"的实例page.html,我将如何使用postMessage做到这一点,当我可以使"根实例URL"提供给每个iFrame?

谢谢!

问题:

window.top似乎是我的朋友,因为它返回最顶部的窗口元素。

当我postMessage to:

var top = window.top;
top.postMessage("foo", currentFrameUrl);

工作正常

我将继续传递URL虽然,因为在跨域iFrames, window.top肯定不会工作…

parent.postMessage("foo");应该可以满足您的要求,如果您只想增加一层嵌套的话。
注意:window是隐含的,所以你实际执行的是window.parent.postMessage("foo");

第二个参数只有在跨域工作时才需要(即,如果您的父和嵌套的iframe具有不同的协议/子域/域/端口),在这种情况下,"*"是技术上可接受的跨域发送postMessage的解决方案,尽管这可能不太安全。