使用window.postMessage可以进行跨域同步通信吗?

8
我正在考虑直接使用window.postMessage进行跨域通信。
如果我这样做:
  1. 从父框架中使用postMessage()
  2. 加载一个iframe
  3. 在子iframe中使用window.addEventListener("message", callback, false);
那么在加载iframe之前我发布的消息将在什么时候执行?它们是否保证会被执行?是否有时间保证?
我想从顶层框架传递一个参数,以影响子框架的初始化。
2个回答

10

postMessage()函数是异步的,这意味着它会立即返回。因此,您不能通过同步通信来使用它。

在您的示例中,发布的消息将消失在虚空中,因为在执行postMessage()函数时没有侦听器在消息事件上。

如果您先加载iframe,然后再调用postMessage(),可能会出现时间问题。(根据我的经验,父代码总是先执行,但我对这一点不确定。)

以下是我解决不知道iframe何时准备就绪的问题的解决方案。

在父窗口中:

  1. 加载iframe(这也是异步的)
  2. 设置消息侦听器
  3. 向iframe发送消息(只是在这里尝试)
  4. 等待更多的消息到来

在iframe中:

  1. 设置消息侦听器
  2. 向父窗口发送消息(只是在这里尝试)
  3. 等待更多的消息到来

谁从另一侧收到第一条消息,就开始了真正的通信。

根据我的经验,从父级到iframe的消息总是丢失的,因此当父级收到来自iframe的消息时,通信才开始。但是在这种设置中,哪个先开始并不重要。


postMessage()函数是异步的,这意味着它会立即返回。您是否意味着它不会立即返回?同步意味着它会立即返回。 - TemporaryFix
我相信根据MDN,postMessage的返回类型是voidNone (undefined)。因此它应该被忽略。它不会像Promises一样立即返回有用的东西。我认为这是我们没有追踪的副作用。 - MadJoRR

1
要从父窗口发送第一条消息到iframe,只有在iframe加载完成之后才能发送消息,甚至在此之前你不能从子窗口向父窗口发送消息。因此,为iframe提供一个onload处理程序,以便可以使用postmessge()发送消息。请考虑以下代码。
ifrm.setAttribute('src','www.yoururl.com'));
document.body.appendChild(ifrm);
ifrm.onload = function() {
   this.contentWindow.postMessage(dataObject,'targetWindow');
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接