Chrome上的window.postMessage问题 [英] Problems with window.postMessage on Chrome

查看:1390
本文介绍了Chrome上的window.postMessage问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经坚持了几个小时.

I have been stuck on this for hours.

我在 http://example.com 上有一个.html,其中包含带有src的iframe b.html在 http://subdomain.example.com 上. a.html有一些JS代码 将消息发布到iframe.

I have a.html on http://example.com that contains an iframe with src to b.html on http://subdomain.example.com. a.html has some JS code to postMessage to the iframe.

postMessage的代码很简单:

The code to postMessage is simple:

iframe_window.postMessage('message', iframe_element.src)

但是这样,Chrome会抛出错误:

But this way, Chrome throws an error:

Unable to post message to http://subdomain.example.com. Recipient has origin null.

我也尝试过:

iframe_window.postMessage('message', 'http://subdomain.example.com')

但是没有运气!

这是唯一可行的方法:

iframe_window.postMessage('message', '*')

但是我听说'*'不好用.

But I have heard '*' is not good to use.

在Firefox中没有问题.

No problems in Firefox.

推荐答案

看来这可能是由于在发送信号时未加载子iframe的问题,因此iframe.src没有正确的设置值.

It looks like this might be an issue with the child iframe not being loaded at the time the signal is sent, thus iframe.src doesn't have the proper value.

我做了一些测试,并得到了与您相同的错误,但是当我将postMessage调用包装在setTimeout中并等待100ms时,没有任何错误,这告诉我这是一个初始化竞争条件.

I did some testing and got the same error as you, but when I wrapped the postMessage call in a setTimeout and waited 100ms then there was no error, which tells me that this is an initialisation race condition.

这是我在没有setTimeout的情况下实施更干净的解决方案的方法:

Here's how I implemented a cleaner solution without the setTimeout:

父母:

window.addEventListener("DOMContentLoaded", function() {

    var iframe = document.querySelector("iframe")
      , _window = iframe.contentWindow

    window.addEventListener("message", function(e) {

        // wait for child to signal that it's loaded.
        if ( e.data === "loaded" && e.origin === iframe.src.split("/").splice(0, 3).join("/")) {

            // send the child a message.
            _window.postMessage("Test", iframe.src)
        }
    })

}, false)

孩子:

window.addEventListener("DOMContentLoaded", function() {

    // signal the parent that we're loaded.
    window.parent.postMessage("loaded", "*")

    // listen for messages from the parent.
    window.addEventListener("message", function(e) {

        var message = document.createElement("h1")

        message.innerHTML = e.data

        document.body.appendChild(message)

    }, false)

}, false)

这是一个简单的解决方案,其中子进程将向任何人发出信号,告知其已加载(使用"*",这没关系,因为没有发送任何敏感信息.)父进程侦听已加载的事件并检查其是否为子进程它对发出它感兴趣.

This is a simple solution in which the child will signal to anyone that it's loaded (using "*", which is okay, because nothing sensitive is being sent.) The parent listens for a loaded event and checks that it's the child that it's interested in that's emitting it.

然后,父母将消息发送给孩子,准备接收它.当孩子收到消息时,它将数据放在< h1>消息中.并将其附加到< body>.

The parent then sends a message to the child, which is ready to receive it. When the child gets the message it puts the data in an <h1> and appends that to the <body>.

我在Chrome中使用实际的子域对其进行了测试,并且该解决方案对我有用.

I tested this in Chrome with actual subdomains and this solution worked for me.

这篇关于Chrome上的window.postMessage问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆