javascript:监听来自特定 iframe 的 postMessage 事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16266474/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 03:58:42  来源:igfitidea点击:

javascript: listen for postMessage events from specific iframe

javascripthtmliframepostmessage

提问by forresto

I have multiple iframes in a page. Now I have one messageevent listener for the page, which gets the messages from all of the iframes. I have a workaround to know from which iframe the message is coming.

我在一个页面中有多个 iframe。现在我有一个message页面的事件侦听器,它从所有 iframe 获取消息。我有一个解决方法来了解消息来自哪个 iframe。

I would like to make event listeners for each iframe separately. Is this possible?

我想分别为每个 iframe 制作事件侦听器。这可能吗?

采纳答案by Ivan Zuzak

No, it's not possible. Best you can do is to have a single handler that routes received messages to helper handlers based on the origin of the message sender.

不,这不可能。您能做的最好的事情是拥有一个处理程序,根据消息发送者的来源将接收到的消息路由到辅助处理程序。

回答by Congelli501

You must listen on the global messageevent of the windowobject, but you can filter the source iframe using the sourceproperty of MessageEvent.

你必须听在全球message的事件window对象,但你可以过滤源iframe中使用source的特性MessageEvent

Example:

例子:

const childWindow = document.getElementById('test-frame').contentWindow;
window.addEventListener('message', message => {
    if (message.source !== childWindow) {
        return; // Skip message in this event listener
    }

    // ...
});

回答by Jan Werkhoven

If the srcattribute of each iframe is unique then you can try this:

如果src每个 iframe的属性都是唯一的,那么您可以尝试以下操作:

On the child:

关于孩子:

function sendHeight() {
  // sends height to parent iframe
  var height = $('#app').height();
  window.parent.postMessage({
    'height': height,
    'location': window.location.href
  }, "*");
}

$(window).on('resize', function() {
  sendHeight();
}).resize();

On the parent:

在父级上:

$(window).on("message", function(e) {
    var data = e.originalEvent.data;
    $('iframe[src^="' + data.location + '"]').css('height', data.height + 'px');
});

The child sends it's height and URL to the iframe parent using postMessage(). The parent then listens for that event, grabs the iframe with that URL and sets the height to it.

孩子使用postMessage(). 然后父级侦听该事件,使用该 URL 抓取 iframe 并为其设置高度。

回答by Maciej Krawczyk

Actually you can. Add a unique name attribute to each iframe. iframe name is passed down to the contentWindow. So inside iframe window.name is the name of the iframe and you can easily send it in post message.

其实你可以。为每个 iframe 添加一个唯一的名称属性。iframe 名称传递给 contentWindow。所以在 iframe window.name 里面是 iframe 的名称,你可以很容易地在 post 消息中发送它。

回答by Jan Werkhoven

You could use e.originalEvent.originto identify the iframe.

您可以e.originalEvent.origin用来识别 iframe。

On the iframe child:

在 iframe 子项上:

window.parent.postMessage({
  'msg': 'works!'
}, "*");

On the iframe parent:

在 iframe 父级上:

Javascript

Javascript

window.addEventListener('message', function(e) {
  console.log(e.origin); // outputs "http://www.example.com/"
  console.log(e.data.msg); // outputs "works!"
  if (e.origin === 'https://example1.com') {
    // do something
  } else if (e.origin === 'https://example2.com'){
    // do something else
  }
}, false);

jQuery

jQuery

$(window).on('message', function(e) {
  ...
}, false);

So origincontains the protocol and domain from which the postMessage()was fired from. It does not include the URI. This technique assume all iframes have a unique domain.

Soorigin包含从中postMessage()触发的协议和域。它不包括 URI。这种技术假设所有 iframe 都有一个唯一的域。

回答by Dan Ochiana

One way of detecting where the message came from is by checking which iframe is focused or for my specific scenario which iframe is visible.

检测消息来自何处的一种方法是检查哪个 iframe 是焦点或在我的特定场景中哪个 iframe 可见。