Comment utilisez-vous window.postMessage sur plusieurs domaines?


89

Il semble que le but de window.postMessage soit de permettre une communication sécurisée entre les fenêtres / cadres hébergés sur différents domaines, mais il ne semble pas le permettre dans Chrome.

Voici le scénario:

  1. Incorporer un <iframe> (avec un srcsur le domaine B * ) dans une page du domaine A
  2. Le <iframe> finit par être principalement une balise <script>, à la fin de l'exécution de laquelle ...
  3. J'appelle window.postMessage ( some_data , page_on_A )

Le <iframe> est très certainement dans le contexte du domaine B, et j'ai confirmé que le javascript intégré dans ce <iframe> s'exécute correctement et appelle postMessageavec les valeurs correctes.

Je reçois ce message d'erreur dans Chrome:

Impossible de poster un message à A . Bénéficiaire a l' origine B .

Voici le code qui enregistre un écouteur d'événement de message dans la page sur A:

window.addEventListener(
  "message",
  function (event) {
    // Do something
  },
  false);

J'ai également essayé d'appeler window.postMessage(some_data, '*'), mais tout ce que cela fait est de supprimer l'erreur.

Suis-je juste en train de manquer le point ici, window.postMessage (...) n'est-il pas destiné à cela? Ou est-ce que je le fais horriblement mal?

* Texte de type Mime / html, qu'il doit rester.


1
Vous en êtes probablement déjà conscient, mais MDC a un excellent récapitulatif sur postMessage: developer.mozilla.org/en/DOM/window.postMessage Pour l'implémentation de FF évidemment, mais peut-être qu'il y a là quelque chose qui explique pourquoi cela ne fonctionne pas.
Pekka

Réponses:


79

Voici un exemple qui fonctionne sur Chrome 5.0.375.125.

La page B (contenu iframe):

<html>
    <head></head>
    <body>
        <script>
            top.postMessage('hello', 'A');
        </script>
    </body>
</html>

Notez l'utilisation top.postMessageou parent.postMessagepas window.postMessageici

La page A:

<html>
<head></head>
<body>
    <iframe src="B"></iframe>
    <script>
        window.addEventListener( "message",
          function (e) {
                if(e.origin !== 'B'){ return; } 
                alert(e.data);
          },
          false);
    </script>
</body>
</html>

A et B doivent être quelque chose comme http://domain.com

ÉDITER:

À partir d' une autre question , il semble que les domaines (A et B ici) doivent avoir un /pour que le postMessagefonctionne correctement.


3
Lorsque la page A vérifie l'origine du message, l'origine ne contiendra PAS de «/» à la fin. Il ne semble pas important que la page B spécifie un «/» de fin ou non. L'autre chose à noter est que les URL doivent être des URL absolues.
Catch

1
Cette réponse m'a laissé un peu confus et toujours à la recherche d'une réponse. blog.teamtreehouse.com/cross-domain-messaging-with-postmessage contient une très bonne explication du postMessage. Ce qui est important, c'est que l'expéditeur du message connaisse le domaine du destinataire. Dans l'exemple ci-dessus, A et B ne doivent pas nécessairement être les mêmes domaines, mais B doit savoir exactement quel domaine est utilisé par A.
Greg Bogumil

7
La question concerne le cross-domain. La réponse acceptée concerne le même domaine.
stackular

@stackular, pas exactement. A et B peuvent être n'importe quel domaine. C'est la raison principale d'avoirpostMessage
Mic

1
+1. Nous voulons confirmer que cette solution a fonctionné sur notre cas. Nous avons une page qui contient un iframe d'un domaine différent . Veuillez noter que cela ne fonctionne que dans le navigateur Chrome, car dans Firefox, nous devons utiliser window.parent.postMessage au lieu de top . Bien que nous ne sachions pas si cela peut être appliqué à un autre navigateur.
rahmatns le

24

Vous devez publier un message du cadre au parent, après le chargement.

script de trame:

$(document).ready(function() {
    window.parent.postMessage("I'm loaded", "*");
});

Et écoutez-le en parent:

function listenMessage(msg) {
    alert(msg);
}

if (window.addEventListener) {
    window.addEventListener("message", listenMessage, false);
} else {
    window.attachEvent("onmessage", listenMessage);
}

Utilisez ce lien pour plus d'informations: http://en.wikipedia.org/wiki/Web_Messaging


2

Vous essayez probablement d'envoyer vos données de mydomain.com à www.mondomaine.com ou inversement, REMARQUE vous avez manqué "www". http://mondomaine.com et http://www.mydomaine.com sont des domaines différents de javascript.


2
Dans un projet que je fais, j'utilise file:/// Est-il possible d'obtenir des erreurs de domaine lors de l'extraction de contenu uniquement à partir du système de fichiers local?
Jacksonkr
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.