2010-08-11 2 views
74

Sembra che il punto di window.postMessage consenta la comunicazione sicura tra finestre/frame ospitati su domini diversi, ma in realtà non sembra che consenta in Chrome.Come si usa window.postMessage attraverso i domini?

Ecco lo scenario:

  1. incorporare un <iframe> (con un src sul dominio B *) in una pagina sul dominio A
  2. Il <iframe> finisce per essere per lo più uno script <Tag>, al termine del quale è in esecuzione ...
  3. Io chiamo window.postMessage (some_data, page_on_A)

Il <iframe> è sicuramente nel contesto di dominio B, e ho confermato che il JavaScript incorporato in quel <iframe> esegue correttamente e chiama postMessage con i valori corretti.

ricevo questo messaggio di errore in Chrome:

Impossibile inviare un messaggio a A. Il destinatario ha origine B.

Ecco il codice che registra un messaggio di evento ascoltatore in 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 è sopprimere l'errore.

Mi manca solo il punto qui, window.postMessage (...) non è pensato per questo? O sto semplicemente sbagliando?

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

+1

si sono probabilmente consapevoli di questo già, ma MDC ha un ottimo resoconto su postMessage: https://developer.mozilla.org/en/DOM/window.postMessage Per l'implementazione FF ovviamente, ma forse c'è qualcosa che spiega perché non funziona. –

risposta

66

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.postMessage o parent.postMessage non window.postMessage qui

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 deve essere qualcosa come http://domain.com

EDIT:

Da another question, sembra i domini (A e B qui) deve avere un / per il postMessage per funzionare correttamente.

+3

Quando la pagina A controlla l'origine del messaggio, l'origine NON conterrà un "/" finale. Non sembra importare se la pagina B specifica un "/" finale o meno. L'altra cosa da notare è che gli URL dovrebbero essere URL assoluti. – Catch22

+1

Questa risposta mi ha lasciato un po 'confuso e ancora alla ricerca di una risposta. http://blog.teamtreehouse.com/cross-domain-messaging-with-postmessage contiene una spiegazione molto buona 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 viene utilizzato da A. –

+1

La domanda riguarda il dominio incrociato. La risposta accettata riguarda lo stesso dominio. – stackular

1

Probabilmente si prova a inviare i dati da mydomain.com a www.mydomain.com o viceversa, NOTA che si è perso "www". http://mydomain.com e http://www.mydomain.com sono diversi domini di javascript.

+1

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

15

Si dovrebbe inviare un messaggio da frame a padre, dopo aver caricato.

script di fotogrammi:

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

E ascolta nel genitore:

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

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

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