Come comunicare tra iframe e il sito padre?


185

Il sito Web nell'iframe non si trova nello stesso dominio , ma entrambi sono miei e vorrei comunicare tra il iframesito padre e quello padre. È possibile?

Risposte:


308

Con domini diversi, non è possibile chiamare metodi o accedere direttamente al documento di contenuto dell'iframe.

Devi usare la messaggistica tra documenti .

Ad esempio nella finestra in alto:

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

e nell'iframe:

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

Se stai pubblicando un messaggio da iframe nella finestra principale

window.top.postMessage('hello', '*')

2
grazie, ma sfortunatamente non funziona nei browser più vecchi.
Danny Fox,

106
Nel genitore: window.onmesage = function().... window.top.postMessage('hello', '*')
Nell'iframe

3
Non è un bug. Gli URL dei file possono essere molto pericolosi e i browser li stanno trattando con sempre maggiore cura. Ai vecchi tempi era possibile inserire un collegamento file://C:/Windows/system32/whateverin una pagina Web e farlo puntare direttamente nella cartella di sistema dell'utente. Al giorno d'oggi i browser ignorano principalmente i clic su collegamenti del genere. Esegui un server web e accedi al tuo codice attraverso quello e vedrai gli errori apparire.
Stijn de Witt,

4
Come buona pratica, non usare mai '*' per il tuo obiettivo. In effetti, MDN dice: "Fornisci sempre un targetOrigin specifico, non *, se sai dove dovrebbe trovarsi il documento dell'altra finestra. Se non fornisci un target specifico, vengono divulgati i dati che invii a qualsiasi sito dannoso interessato."
Rodiwa,

2
Possiamo persino usare window.frames[index]per ottenere un frame figlio ( <iframe>, <object>, <frame>), equivalente a getElementsByTagName("iframe")[index].contentWindow. Per ottenere l'oggetto della finestra padre da IFrame, è meglio usarlo window.parent, poiché window.toprappresenta la finestra principale più padre
phoenisx

46

Deve essere qui, perché risposta accettata dal 2012

Nel 2018 e nei browser moderni puoi inviare un evento personalizzato da iframe alla finestra principale.

iframe:

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

genitore:

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

PS: Certo, puoi inviare eventi nella direzione opposta allo stesso modo.

document.querySelector('#iframe_id').contentDocument.dispatchEvent(event)

1
Ciao, devo essere nello stesso dominio per farlo?
Guillaume Harari,


1
Va notato che dispatchEventè supportato in tutti i principali browser. IE9 è stata la prima versione in arrivo, quindi la maggior parte dei sistemi operativi ora funziona con esso. caniuse.com/#search=dispatchEvent
Dan Atkinson

1
Non sono in grado di comunicare dal genitore all'iframe con questo metodo.
Avan,

Sì, non riesco nemmeno a farlo funzionare, l'iframe js si sta caricando dopo la finestra principale, quindi non è lì per ricevere il messaggio quando viene inviato. funziona solo da iframe a genitore per me.
Radtek,

14

Questa libreria supporta i postMessage e i browser legacy HTML5 con resize + hash https://github.com/ternarylabs/porthole

Modifica: ora nel 2014, l'utilizzo di IE6 / 7 è piuttosto basso, IE8 e soprattutto il supporto postMessagequindi ora suggerisco di usarlo.

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


Con l'avvertenza che IE8 / 9 supporta solo stringhe caniuse.com/#search=postmessage (Vedi i problemi noti)
Harry

questo può essere aggirato codificando gli oggetti evento in json e decodificandoli dall'altra parte.
codewandler,



1

Utilizzare event.source.window.postMessageper rispedire al mittente.

Da Iframe

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

Quindi dal genitore rispondi.

window.onmessage = (event) => {
    event.source.window.postMessage('GOT_YOU_IFRAME', '*')
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.