[Questo post è stato pubblicato a gennaio 2011 e viene ancora consultato molto spesso: ecco perché lo teniamo online]
Qui a Cakemail stiamo sviluppando una piattaforma che permetterà ai nostri utenti di creare moduli e incorporarli direttamente nel loro sito web (pensa, ad esempio, a un modulo di iscrizione a una mailing list). Insomma, avevamo bisogno di un controllo JavaScript sia nell'elemento padre che in quello figlio.
Avevamo due problemi da risolvere legati all’incorporamento. Uno era quello di modificare dinamicamente l’altezza dell’iframe (non avremmo mai e poi mai salvato l’altezza dell’iframe in un database). E a volte, a seconda delle funzionalità che i nostri utenti incorporavano nel loro sito web, dovevamo effettivamente reindirizzare la pagina principale.

Perché è così difficile?
Sicurezza: sono sicuro che non c’è proprio bisogno che ti spieghi cosa potrebbe fare un malintenzionato al tuo sito web se avesse accesso al tuo documento. Potrebbe inserirsi nella procedura di accesso e rubare le email e le password di tutti i tuoi utenti, reindirizzare il tuo sito web, ecc. Ecco perché l’implementazione di una comunicazione tra domini non va presa alla leggera.
Anche se lo fai nel modo giusto, devi pensare a cosa potrebbe succedere se lo script incorporato venisse compromesso. Soprattutto se lo incorpori in altri siti web che non sono tuoi!
Come accedere a una finestra principale e a un documento
Accedere a un documento padre è davvero semplice quando ti trovi sullo stesso dominio: basta un rapido `window.opener.MyParentFunction()` e il gioco è fatto.
Ma farlo tra domini diversi? Non è così facile. Ti verrà fuori qualcosa del tipo: “Il documento figlio non ha i diritti per accedere al documento padre”. In realtà sul web c’è un sacco di documentazione su come farlo, ma il problema è che spesso è obsoleta, con soluzioni che funzionano solo su un paio di browser.
Il metodo vecchio stile: un iframe dentro un iframe dentro un iframe
Un’idea ingegnosa che è spuntata fuori qualche tempo fa: incorporare un iframe nella finestra figlia che si trovi sullo stesso dominio della finestra padre. Funziona, il più delle volte, ma ci sono delle varianti di questa tecnica: alcune funzionano, altre no. Alcune varianti prevedono che l’URL utilizzi un hash (#) per passare i dati, il che è davvero pessimo se vuoi trasferire molti dati, oltre a causare fastidiosi disturbi in IE e una cronologia di navigazione orribile.
Ma ricorda che si tratta comunque di un trucchetto. Stai aggirando la protezione con un espediente piuttosto ingegnoso, e c’è sempre la possibilità che un giorno smetta di funzionare con un aggiornamento del browser.
Una bella risorsa per i veterani del mestiere
Questo sito spiega davvero nei minimi dettagli come far funzionare gli "hack" con gli iframe. È davvero utile se vuoi capire a fondo come funziona la politica cross-domain degli iframe.
Il metodo HTML5
Ahhh, l’HTML5, la soluzione a tutti i nostri problemi… vero? Per il problema del cross-domain, l’HTML5 ha introdotto un nuovo metodo JavaScript davvero utile: postmessage.
window.postmessage è stato implementato proprio per risolvere il problema delle politiche cross-domain, in modo sicuro (o almeno il più sicuro possibile...). Ecco come si presenterebbe una comunicazione:
Sono disponibili 2 opzioni per renderlo il più sicuro possibile: "origin" e "source". "Origin" indica il dominio di origine del messaggio, mentre "source" fa riferimento all'oggetto window.
E Internet Explorer?
Postmessage è presente in IE8, ma non in IE7 e IE6 (ovviamente). Se devi supportare quei browser, dovrai ricorrere a un’altra tecnica.
Puoi trovare una descrizione davvero completa ed esempi relativi a `postmessage` sul sito della documentazione JavaScript di Mozilla.
Come al solito, per avere una soluzione che funzioni bene su tutti i browser, dobbiamo scendere a qualche compromesso
Come per molte cose che riguardano il DOM, il modo migliore per garantire la compatibilità tra i vari browser è usare la soluzione migliore possibile e ricorrere a qualche espediente per i browser più vecchi.
Per fortuna, è proprio quello che ha fatto easyXDM per te. Questa libreria è (o è stata) usata da tantissimi siti web, tra cui Twitter e Disqus! Ti offre un’API davvero comoda che funziona ovunque. Diamo un’occhiata:
E con IE? Come fa easyXDM a fare la sua magia?
Verrebbe da pensare che easyXDM usi il semplice trucchetto degli iframe per funzionare su IE7 e IE6, ma in realtà usa un espediente molto più ingegnoso. Utilizza un protocollo esclusivo di IE (una sorta di VBScript) che rende possibile la comunicazione tra domini diversi: il NixTransport.
“Questa implementazione, quindi, racchiude gli oggetti JavaScript all’interno di una classe VBScript. Dato che gli oggetti VBScript vengono passati in JavaScript come wrapper COM (proprio come gli oggetti DOM), risultano quindi opachi per JavaScript (ad eccezione dell’interfaccia che espongono). Questo garantisce quindi un metodo di trasporto sicuro. Inizialmente basato su FrameElementTransport, che presenta alcune somiglianze con questo metodo.”
Limiti
Un limite evidente che ho notato usando questa libreria è che, se carichi una finestra figlia senza che sia incorporata nella finestra padre, easyXDM genera un errore JavaScript. Sul forum ci sono dei modi per risolvere il problema usando una terza finestra, ma non è proprio comodo; ho anche fatto qualche prova con l’opzione onReady. All’inizio sembrava funzionare, ma a volte genera comunque un errore.
Per quel che vale, è comunque la libreria più potente che ho trovato in giro: ho inviato un messaggio da 1 MB ed è arrivato lo stesso, anche su IE7, ed è davvero veloce.
Ecco fatto!
Spero che questo ti aiuti a far funzionare tutte le tue comunicazioni tra domini!
Questo articolo è stato scritto da Cedric Dugas, ex sviluppatore di interfacce presso Cakemail. Puoi seguire Cedric su Twitter @posabsolute.



