Come si utilizza window.postMessage nei domini?


89

Sembra che lo scopo di window.postMessage sia quello di consentire una comunicazione sicura tra finestre / frame ospitati su domini diversi, ma in realtà non sembra consentirlo in Chrome.

Ecco lo scenario:

  1. Incorpora un <iframe> (con un srcnel dominio B * ) in una pagina nel dominio A
  2. Il <iframe> finisce per essere principalmente un tag <script>, alla fine del quale l'esecuzione ...
  3. Chiamo window.postMessage ( some_data , page_on_A )

Il <iframe> è decisamente nel contesto del dominio B e ho confermato che il javascript incorporato in quel <iframe> viene eseguito correttamente e chiama postMessagecon i valori corretti.

Ottengo questo messaggio di errore in Chrome:

Impossibile inviare un messaggio a A . Destinatario è di origine B .

Ecco il codice che registra un listener di eventi di messaggio nella pagina su A:

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

Ho anche provato a chiamare window.postMessage(some_data, '*'), ma tutto ciò che fa è eliminare l'errore.

Mi manca solo il punto qui, window.postMessage (...) non è pensato per questo? O lo sto facendo orribilmente sbagliato?

* Mime-type text / html, che deve rimanere.


1
Probabilmente lo saprai già, ma MDC ha un eccellente riassunto di postMessage: developer.mozilla.org/en/DOM/window.postMessage Ovviamente per l'implementazione di FF, ma forse c'è qualcosa che spiega perché non funziona.
Pekka

Risposte:


79

Ecco un esempio che funziona su Chrome 5.0.375.125.

La pagina B (contenuto iframe):

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

Nota l'uso di top.postMessageo parent.postMessageno window.postMessagequi

La pagina 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 e B devono essere qualcosa di simile http://domain.com

MODIFICARE:

Da un'altra domanda , sembra che i domini (A e B qui) debbano avere una /per postMessagefunzionare correttamente.


3
Quando la pagina A controlla l'origine del messaggio, l'origine NON conterrà una "/" finale. Non sembra avere importanza se la pagina B specifica un '/' finale o meno. L'altra cosa da notare è che gli URL dovrebbero essere URL assoluti.
Cattura il 22

1
Questa risposta mi ha lasciato un po 'confuso e ancora alla ricerca di una risposta. blog.teamtreehouse.com/cross-domain-messaging-with-postmessage contiene un'ottima spiegazione del postMessage. Ciò che è importante è che il mittente del messaggio conosca il dominio del destinatario. Nell'esempio sopra, A e B non devono essere gli stessi domini, ma B deve sapere esattamente quale dominio è utilizzato da A.
Greg Bogumil

7
La domanda riguarda il cross-domain. La risposta accettata riguarda lo stesso dominio.
stackular

@stackular, non esattamente. A e B possono essere qualsiasi dominio. Questo è il motivo principale per cuipostMessage
Mic

1
+1. Vogliamo confermare che questa soluzione ha funzionato sul nostro caso. Abbiamo una pagina che contiene un iframe di un dominio diverso . Tieni presente che funziona solo nel browser Chrome, poiché in Firefox dobbiamo utilizzare window.parent.postMessage anziché top . Anche se non sappiamo se questo può essere applicato a qualsiasi altro browser.
rahmatns

24

Dovresti pubblicare un messaggio dal frame al genitore, dopo averlo caricato.

script frame:

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

E ascoltalo in genitore:

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

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

Usa questo link per maggiori informazioni: http://en.wikipedia.org/wiki/Web_Messaging


2

Probabilmente provi a inviare i tuoi dati da miodominio.com a www.miodominio.com o viceversa, NOTA ti sei perso "www". http://mydomain.com e http://www.mydomain.com sono domini diversi da javascript.


2
In un progetto che sto facendo, sto usando file:/// È possibile ottenere errori di dominio quando si estrae il contenuto esclusivamente dal file system locale?
Jacksonkr
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.