我被困在这几个小时。
我在http://example.com上有一个a.html,其中包含一个带有src的iframe b.html在http://subdomain.example.com上。 a.html有一些JS代码 将postMessage发送到iframe。
postMessage的代码很简单:
iframe_window.postMessage('message', iframe_element.src)
但是这样,Chrome就会抛出错误:
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', '*')
但我听说'*'不好用。
Firefox中没有问题。
答案 0 :(得分:18)
看起来这可能是在发送信号时没有加载子iframe的问题,因此iframe.src没有正确的值。
我做了一些测试并得到了与你相同的错误,但当我在setTimeout中包装postMessage调用并等待100ms时,没有错误,这告诉我这是初始化竞争条件。
以下是我在没有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)
这是一个简单的解决方案,在这个解决方案中,孩子会向任何人发出信号(使用“*”,这是好的,因为没有敏感信息被发送。)父母听取加载的事件并检查它是否是孩子它对发射它感兴趣。
父母然后向孩子发送一条消息,该消息已准备好接收它。当孩子得到消息时,它将数据放在< h1>中。并将其附加到< body>。
我在Chrome中使用实际子域进行了测试,此解决方案适用于我。
答案 1 :(得分:0)
更短的解决方案是将 postMessage 包裹在 iframe_element.onload 函数中。