Wie kommuniziere ich zwischen iframe und der übergeordneten Site?

183

Die Website im Iframe befindet sich nicht in derselben Domain , aber beide gehören mir, und ich möchte zwischen der iframeund der übergeordneten Site kommunizieren . Ist es möglich?

Danny Fox
quelle

Antworten:

303

Bei verschiedenen Domänen ist es nicht möglich, Methoden aufzurufen oder direkt auf das Inhaltsdokument des Iframes zuzugreifen.

Sie müssen dokumentenübergreifendes Messaging verwenden .

Zum Beispiel im oberen Fenster:

 myIframe.contentWindow.postMessage('hello', '*');

und im iframe:

window.onmessage = function(e){
    if (e.data == 'hello') {
        alert('It works!');
    }
};

Wenn Sie eine Nachricht vom Iframe an das übergeordnete Fenster senden

window.top.postMessage('hello', '*')
user123444555621
quelle
2
Danke, aber leider funktioniert es nicht in älteren Browsern.
Danny Fox
106
Im Elternteil : window.onmesage = function().... Im iframe:window.top.postMessage('hello', '*')
user123444555621
3
Es ist kein Fehler. Datei-URLs können sehr unsicher sein und werden von Browsern mit immer größerer Sorgfalt behandelt. Früher konnten Sie einen Link file://C:/Windows/system32/whateverauf eine Webseite setzen und ihn direkt in den Systemordner des Benutzers verweisen. Heutzutage ignorieren Browser Klicks auf solche Links meistens. Führen Sie einen Webserver aus und greifen Sie über diesen auf Ihren Code zu. Die Fehler werden angezeigt.
Stijn de Witt
4
Verwenden Sie als bewährte Methode niemals das '*' für Ihr Ziel. Tatsächlich sagt MDN: "Geben Sie immer ein bestimmtes targetOrigin an, nicht *, wenn Sie wissen, wo sich das Dokument des anderen Fensters befinden soll. Wenn Sie kein bestimmtes Ziel angeben, werden die Daten offengelegt, die Sie an eine interessierte böswillige Site senden."
Rodiwa
2
Wir können sogar verwenden window.frames[index], um child frame ( <iframe>, <object>, <frame>) zu erhalten, was äquivalent zu ist getElementsByTagName("iframe")[index].contentWindow. Um window.parentwindow.top
Subroto
44

Es muss hier sein, da akzeptierte Antwort von 2012

In 2018 und modernen Browsern können Sie ein benutzerdefiniertes Ereignis vom Iframe an das übergeordnete Fenster senden.

iframe:

var data = { foo: 'bar' }
var event = new CustomEvent('myCustomEvent', { detail: data })
window.parent.document.dispatchEvent(event)

Elternteil:

window.document.addEventListener('myCustomEvent', handleEvent, false)
function handleEvent(e) {
  console.log(e.detail) // outputs: {foo: 'bar'}
}

PS: Natürlich können Sie Ereignisse auf die gleiche Weise in die entgegengesetzte Richtung senden.

document.querySelector('#iframe_id').contentDocument.dispatchEvent(event)
Fremder im Q.
quelle
1
Hallo, muss ich mich auf derselben Domain befinden, um dies zu tun?
Guillaume Harari
1
Es ist zu beachten, dass dispatchEventdies in allen gängigen Browsern unterstützt wird. IE9 war die erste Version, die es gab, daher arbeiten die meisten Betriebssysteme jetzt damit. caniuse.com/#search=dispatchEvent
Dan Atkinson
1
Ich kann mit dieser Methode nicht vom Elternteil zum Iframe kommunizieren.
Avan
Ja, ich kann es auch nicht zum Laufen bringen. Der Iframe js wird nach dem übergeordneten Fenster geladen, sodass er beim Senden nicht zum Empfangen der Nachricht vorhanden ist. es funktioniert nur von iframe zu parent für mich.
Radtek
14

Diese Bibliothek unterstützt HTML5-PostMessage- und Legacy-Browser mit Resize + Hash https://github.com/ternarylabs/porthole

Bearbeiten: Jetzt im Jahr 2014 ist die IE6 / 7-Nutzung ziemlich gering, IE8 und vor allem Unterstützung, postMessagedaher schlage ich jetzt vor, nur diese zu verwenden.

https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage

jpillora
quelle
Mit der Einschränkung, dass IE8 / 9 nur Zeichenfolgen unterstützt caniuse.com/#search=postmessage (Siehe bekannte Probleme)
Harry
Dies kann umgangen werden, indem Sie Ihre Ereignisobjekte in json codieren und auf der anderen Seite decodieren.
Codewandler
3

Die window.topUnterkunft sollte in der Lage sein, das zu geben, was Sie benötigen.

Z.B

alert(top.location.href)

Siehe http://cross-browser.com/talk/inter-frame_comm.html

Sambomartin
quelle
10
Da sich der Iframe nicht in derselben Domäne befindet, kann er nicht auf die übergeordnete Domäne zugreifen.
Andreas Köberle
1

Sie können auch verwenden

postMessage(message, '*');;

gonzarodriguezt
quelle
1

Verwenden Sie event.source.window.postMessagediese Option, um an den Absender zurückzusenden.

Von Iframe

window.top.postMessage('I am Iframe', '*')
window.onmessage = (event) => {
    if (event.data === 'GOT_YOU_IFRAME') {
        console.log('Parent received successfully.')
    }
}

Dann sagen die Eltern zurück.

window.onmessage = (event) => {
    event.source.window.postMessage('GOT_YOU_IFRAME', '*')
}
Binh Ho
quelle