Comment communiquer entre iframe et le site parent?


185

Le site Web dans l'iframe ne se trouve pas dans le même domaine , mais les deux sont à moi, et j'aimerais communiquer entre le iframeet le site parent. C'est possible?

Réponses:


309

Avec différents domaines, il n'est pas possible d'appeler des méthodes ou d'accéder directement au document de contenu de l'iframe.

Vous devez utiliser la messagerie inter-document .

Par exemple dans la fenêtre du haut:

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

et dans l'iframe:

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

Si vous publiez un message d'iframe dans la fenêtre parent

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

2
merci, mais malheureusement cela ne fonctionne pas dans les anciens navigateurs.
Danny Fox

106
Dans le parent: window.onmesage = function().... Dans l'iframe:window.top.postMessage('hello', '*')
user123444555621

3
Ce n'est pas un bug. Les URL de fichiers peuvent être très dangereuses et les navigateurs les traitent avec une attention toujours plus grande. Dans l'ancien temps, vous pouviez mettre un lien vers file://C:/Windows/system32/whateverune page Web et le faire pointer directement dans le dossier système de l'utilisateur. De nos jours, les navigateurs ignorent généralement les clics sur des liens comme celui-ci. Exécutez un serveur Web et accédez à votre code via celui-ci et vous verrez les erreurs apparaître.
Stijn de Witt

4
Comme bonne pratique, n'utilisez jamais le «*» pour votre cible. En fait, MDN dit: "Fournissez toujours une cible spécifique, pas *, si vous savez où le document de l'autre fenêtre doit être situé. Ne pas fournir une cible spécifique révèle les données que vous envoyez à tout site malveillant intéressé."
rodiwa

2
Nous pouvons même utiliser window.frames[index]pour obtenir child frame ( <iframe>, <object>, <frame>), équivalent à getElementsByTagName("iframe")[index].contentWindow. Pour obtenir un objet de fenêtre parent à partir d'IFrames, il est préférable d'utiliser window.parent, comme le window.topreprésente la fenêtre la plus parente
phoenisx

46

Il doit être ici, car réponse acceptée de 2012

En 2018 et dans les navigateurs modernes, vous pouvez envoyer un événement personnalisé de l'iframe à la fenêtre parent.

iframe:

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

parent:

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

PS: Bien sûr, vous pouvez envoyer des événements dans la direction opposée de la même manière.

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

1
Bonjour, dois-je être sur le même domaine pour le faire?
Guillaume Harari


1
Il convient de noter qu'il dispatchEventest pris en charge dans tous les principaux navigateurs. IE9 était la première version, donc la plupart des systèmes d'exploitation fonctionnent maintenant avec. caniuse.com/#search=dispatchEvent
Dan Atkinson

1
Je ne peux pas communiquer de parent à iframe avec cette méthode.
Avan le

Ouais, je ne peux pas le faire fonctionner non plus, l'iframe js se charge après la fenêtre parent donc il n'est pas là pour recevoir le msg lorsqu'il est envoyé. cela ne fonctionne que de l'iframe au parent pour moi.
radtek

14

Cette bibliothèque prend en charge les navigateurs HTML5 postMessage et hérités avec redimensionnement + hachage https://github.com/ternarylabs/porthole

Edit: Maintenant, en 2014, l'utilisation d'IE6 / 7 est assez faible, IE8 et surtout le support, postMessagedonc je suggère maintenant de simplement l'utiliser.

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


Avec l'avertissement que IE8 / 9 ne prend en charge que les chaînes caniuse.com/#search=postmessage (voir les problèmes connus)
Harry

cela peut être contourné en encodant vos objets événement en json et en les décodant de l'autre côté.
codewandler



1

Utilisez event.source.window.postMessagepour renvoyer à l'expéditeur.

Depuis Iframe

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

Puis de la part des parents, répondez.

window.onmessage = (event) => {
    event.source.window.postMessage('GOT_YOU_IFRAME', '*')
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.