【问题标题】:how to check from what crossdomain iframe the message (postMessage) came?如何检查消息(postMessage)来自哪个跨域 iframe?
【发布时间】:2012-09-04 21:55:47
【问题描述】:

我知道MessageEventsource 属性,它是发送消息的窗口对象。现在如何让这些信息检查主文档中的哪个 iframe(当然还有消息到达时的主文档中)是该特定消息的来源?只有在event.source 窗口对象上检查location.href 的可用选项,然后循环所有iframe 以检查哪个匹配?如果主文档中存在具有相同源 url 的 iframe 怎么办?

【问题讨论】:

    标签: javascript iframe cross-domain postmessage


    【解决方案1】:

    遍历页面上的所有 iframe,并对其window 对象进行身份比较。

    window.addEventListener('message', function(e) {
        if(e.origin === 'https://www.example.com') {
            var iframes = document.getElementsByTagName('iframe');
    
            for(var i = 0; i < iframes.length; i++) {
                if(e.source === iframes[i].contentWindow) {
                    // Do stuff with iframes[i]
                }
            }
        }
    }
    

    我相信这适用于所有现代浏览器;我很想知道是否有人对此有问题。

    【讨论】:

    • 不错的解决方案!也可以在 Firefox 中使用。
    【解决方案2】:

    如果您尝试读取跨域 iframe/窗口的 location.href 属性,则会引发异常,因为它违反了同源策略。您可以写入该属性,但不能读取。即使这样可行,您也会遇到具有相同 URL 问题的多个 iframe 的问题,正如您所猜测的那样。

    不管怎样,你能做的就是——为某种消息发送确认建立一个协议。换句话说,在接收消息 X 的 iframe 中,您将遍历父文档中的所有 iframe,并向每个 iframe 发送一条消息,询问 “你给我发送消息 X 了吗?”对所有 iframe 进行编程以回答此类问题。当然,您必须将唯一 ID 附加到所有消息,以便您知道哪个 iframe 确认它发送了哪个消息。

    我认为您必须考虑为什么消息的接收者需要知道发件人是谁,以及为什么您只知道对该发件人的引用是不够的 (event.source)?如果发件人知道某些信息 - 那么发件人可以首先在消息中发送此信息。

    【讨论】:

    • 当然,如果您无法控制发件人,则不会。我的页面上有几个隐藏的 Vimeo 嵌入。当用户单击按钮以显示其中一个时,我需要等到从框架中收到“就绪”消息,然后再向其发送“播放”消息。但是如果你的答案是正确的,我无法知道哪个 iframe 说它已经准备好了!这对我来说似乎是一个很大的疏忽。我不知道它如何以任何方式提高安全性,并且无法控制 iframe 页面是一个非常标准的用例。
    【解决方案3】:

    一种更有效的方法是在启动时为每个 iframe 传递一个唯一 ID,并让它们在回发到父框架时使用该 ID。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-11
      • 2014-07-01
      • 1970-01-01
      • 2019-02-03
      • 2011-11-23
      • 2011-08-29
      • 2011-03-20
      • 2012-02-02
      相关资源
      最近更新 更多