Es sieht so aus, als könnte dies ein Problem sein, wenn der untergeordnete Iframe zum Zeitpunkt des Sendens des Signals nicht geladen wird, daher hat iframe.src nicht den richtigen Wert.
Ich habe ein paar Tests und habe den gleichen Fehler wie du, aber wenn ich den PostMessage-Aufruf in einem setTimeout umhüllte und 100ms wartete, dann gab es keinen Fehler, der mir sagt, dass dies eine Initialisierung Race-Bedingung ist.
Hier ist, wie ich eine sauberere Lösung ohne die setTimeout implementiert:
Parent:
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)
Kind:
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)
Dies ist eine einfache Lösung, in der das Kind jedes Signal wird dass es geladen ist (mit "*", was in Ordnung ist, weil nichts Sensitives gesendet wird). Das Elternteil hört auf ein geladenes Ereignis und prüft, ob es das Kind ist, das es inter ist in dem es emittiert.
Der Eltern sendet dann eine Nachricht an das Kind, das bereit ist, es zu empfangen. Wenn das Kind die Nachricht erhält, legt es die Daten in eine <h1> und hängt diese an die < Körper >.
Ich habe dies in Chrome mit tatsächlichen Subdomains getestet und diese Lösung hat für mich funktioniert.
Nur um zu verdeutlichen, verwenden Sie in Ihrem tatsächlichen Code eine echte Website? –