2

我正在尝试使用 postMessage 在页面(在 example1.com 上)和在 example2.com 上的同一页面上的 iframe 之间进行跨域通信

当 iframe 完成加载后,它会使用以下命令向父页面发送 postMessage:

parent.postMessage('你好父母', 'http://example1.com'); //这个命令有效

在父页面(example1.com)中 postMessage 的事件处理程序中,我使用以下函数将响应发送回子页面(example2.com):

//this function is defined in example1.com:

function receiveMessage(event){

    if (event.origin == "http://example2.com"){

        console.log('Message Received from iframe'); //this line works

        event.source.postMessage('hello to you too', event.origin); //this line does not work

    }

}

由于某种原因,未触发 iframe 中 postMessage 的事件处理程序。

//this function is defined in example2.com

function receiveMessage(event){

    if (event.origin == "http://example1.com"){ // I even tried removing this check to no avail

        console.log('Message Received from parent'); //this line works

    }

}

当父级尝试向 iframe 发送消息时,它只会返回 undefined。

任何帮助表示赞赏!

编辑:

我尝试在 example1.com 的 receiveMessage 事件中更改以下行:

event.source.postMessage('你也好', event.origin);

对此:

event.source.postMessage('你也好', 'http://example2.com');

但我收到以下错误:

无法将消息发布到http://example2.com。收件人来源http://example1.com

为什么 event.origin在收到来自 example2.com 的消息时评估为http://example1.com ?

example1.com 正在尝试向自己发送 postMessage。这应该是错误的根源

4

2 回答 2

3

有时 postMessage 可能非常不清楚在哪一帧发送和哪一帧接收。出于这个原因,我创建了一个小脚本来帮助解开帧之间的通信。

将以下代码段添加到您的页面并观察您的控制台以查看会发生什么。确保在与 postMessage 的帧间通信开始之前将其添加到您的页面。

  var listener = function (e) {
    console.log('Caught ', e.type, ' event from ', e.source.self, ' to ', e.target, ' origin ', e.origin, ' with data ', e.data, '. Full details: ', e);
  };

  function addToFrame(el) {
    var frames = el.querySelectorAll('iframe'), ifrm = 0;
    for (var i = 0; i < frames.length; i++) {
      frames[i].contentWindow.addEventListener("message", listener, true);
      ifrm += addToFrame(frames[i].contentWindow.document);
    }
    return i + ifrm;
  }

  window.addEventListener("message", listener, true);
  var c = addToFrame(document);
  console.log('Recursively added listener to main window and', c, 'frames');

在您的控制台中,它清楚地说明了哪个框架将什么发送到哪个其他框架。有关详细信息,请参阅我在我的网站上为您准备的博文。

我希望这将有助于弄清楚 iframe 通信 ;-)

ps 如果这没有帮助,请为您的问题创建一个jsfiddle。这将使我们更容易理解您遇到的问题...

于 2015-05-11T21:36:31.700 回答
0

在我的Vue项目中,我得到了和你一样的结果,最后我把我的起源改成了另一个主机,比如127.0.0.10然后我得到了数据对象

这是我的代码

第一个来源:127.0.0.10:8000

function sendMessage() {
  document
    .getElementById('frame')
    .contentWindow
    .postMessage('Hello world!', '*');
}
<iframe class="d-none" src="http://127.0.0.20:8080/login" onload="sendMessage()" id="frame"></iframe>

第二个来源:127.0.0.10:8000

window.addEventListener(
  "message",
  function (event) {
      if (event.origin.indexOf('127.0.0.10:8000') > 0)
      {
          console.log(event.data);
      }
  }
);

于 2021-10-09T19:29:14.630 回答