![]() |
Quando si sviluppano applicazioni web moderne, capita spesso di dover far comunicare tra loro finestre, iframe o web worker.
In questi casi, il metodo postMessage si rivela uno strumento fondamentale. In questo articolo vedremo cos’è postMessage, a cosa serve e come si utilizza, con esempi pratici.
Cos’è postMessage?
postMessage è un metodo fornito dagli oggetti window e worker in JavaScript, che consente la comunicazione cross-origin (tra contesti diversi), come ad esempio:
- tra una finestra principale e un iframe;
- tra due finestre o tab aperte;
- tra una pagina web e un Web Worker.
A cosa serve?
Serve per inviare dati da un contesto all’altro in modo sicuro, anche se provengono da origini diverse. È utile quando:
- si incorporano widget da altri siti (es. un iframe YouTube);
- si usano Web Worker per eseguire operazioni pesanti in background;
- si aprono finestre popup o si comunicano tab diverse della stessa applicazione.
Come si usa: la sintassi
window.postMessage(message, targetOrigin, [transfer]);
Parametri:
- message: il dato da inviare (può essere stringa, oggetto, array, ecc.).
- targetOrigin: la origine del destinatario (es:
'https://esempio.com'o'*'). - transfer (opzionale): oggetti trasferibili (come ArrayBuffer).
Attenzione a targetOrigin: è obbligatorio
Il secondo parametro di postMessage, chiamato targetOrigin, è obbligatorio secondo le specifiche HTML. Serve a indicare l’origine (protocollo + dominio + porta) del destinatario che deve ricevere il messaggio.
Perché è importante?
- Sicurezza: impedisce che i dati vengano intercettati da origini non autorizzate.
- Controllo: garantisce che il messaggio arrivi solo alla finestra giusta.
Esempi:
// Corretto
iframe.contentWindow.postMessage({ tipo: 'ping' }, 'https://esempio.com');
// Sconsigliato in produzione
iframe.contentWindow.postMessage({ tipo: 'ping' }, '*');
Nota: Anche se in alcuni ambienti JavaScript il parametro può sembrare opzionale, le specifiche HTML richiedono esplicitamente di fornire sempre targetOrigin.
Come ricevere i messaggi: window.addEventListener('message', ...)
Per ricevere un messaggio inviato con postMessage, il ricevente si registra all'evento message che offre l’oggetto event:
window.addEventListener('message', function(event) {
console.log('Dati:', event.data);
console.log('Origine:', event.origin);
console.log('Provenienza:', event.source);
});Spiegazione dei campi:
event.data: il messaggio ricevuto.event.origin: l’origine della finestra mittente (es: https://esempio.com).event.source: un riferimento alla finestra che ha inviato il messaggio.
Esempi (semplici) di utilizzo
Comunicazione tra finestra principale e iframe
<iframe id="myFrame" src="https://altrouser.com/frame.html"></iframe>
// Finestra principale
const iframe = document.getElementById('myFrame');
iframe.contentWindow.postMessage({ type: 'SALUTO', testo: 'Ciao iframe!' }, 'https://altrouser.com');
// Nell’iframe (frame.html)
window.addEventListener('message', function(event) {
if (event.origin !== 'https://tuosito.com') return;
console.log('Messaggio ricevuto:', event.data);
});
Comunicazione tra finestre
// Apri nuova finestra
const popup = window.open('https://esempio.com/popup.html');
// Invia messaggio dopo 1 secondo
setTimeout(() => {
popup.postMessage('Ciao dalla finestra principale!', 'https://esempio.com');
}, 1000);
// Ricevi risposta
window.addEventListener('message', (event) => {
console.log('Risposta dalla popup:', event.data);
});
💘 Quando postMessage può salvarti nello sviluppo
postMessage può davvero salvarti da ore di frustrazione (o dall’impazzire) in molti scenari dello sviluppo web moderno. È una delle API più sottovalutate, ma estremamente utile quando hai a che fare con contesti multipli o sandboxing. postMessage diventa un'ancora di salvezza:🧩 1. Comunicazione tra iframe e pagina principale
Problema: Hai un widget (chat, login, pagamento, etc.) incorporato in un <iframe>, ma non puoi accedere direttamente al suo contenuto (perché è su un dominio diverso).
Soluzione con postMessage:
-
La pagina host invia messaggi all'iframe per dirgli cosa fare (es: cambiare tema).
-
L'iframe invia messaggi alla pagina per notificare eventi (es: "utente loggato").
✅ Eviti hack tipo polling o tentativi illegali di accesso cross-origin.
🌐 2. Integrazione tra microfrontend (diversi domini o team)
Problema: Stai lavorando in un’architettura a microfrontend, dove ogni sezione dell'app è servita da una SPA diversa (e magari da team diversi).
Soluzione con postMessage:
-
Le micro-app comunicano eventi tra loro (es: “utente selezionato”, “logout globale”).
-
Eviti tight coupling tra moduli.
✅ Isolamento + coordinazione = meno bug e team più autonomi.
🔐 3. Autenticazione via popup (OAuth, login esterno)
Problema: Usi un flusso di autenticazione con popup (es. Google Sign-In, Facebook Login) e vuoi ricevere il token nella pagina principale.
Soluzione con postMessage:
-
Il popup, una volta autenticato, invia il token tramite
postMessagealla finestra principale.
✅ Evitato: brutti redirect, uso di URL con token, localStorage condivisi.
📦 4. Editor embeddati o strumenti di terze parti
Problema: Vuoi integrare nel tuo sito uno strumento interattivo (es. editor di testo, grafici, configuratori), ma è ospitato su un dominio esterno.
Soluzione con postMessage:
-
Il tool manda eventi tipo "contenuto aggiornato", "errore", "salvataggio riuscito".
-
Tu puoi rispondere con comandi, impostazioni o contenuti.
✅ Interazione fluida anche con servizi esterni.
🧵 5. Sincronizzazione tra finestre o tab
Problema: Hai la tua app aperta in più tab o finestre, e vuoi tenerle sincronizzate (logout, notifiche, modifiche in tempo reale).
Soluzione con postMessage:
-
Le finestre si inviano eventi tra loro (via
window.opener,window.parent, oBroadcastChannelcome alternativa moderna).
✅ Esperienza utente coerente e centralizzata.
⚙️ 6. Web Worker e performance
Problema: Devi fare operazioni pesanti (calcoli, parsing JSON, trasformazioni) ma non vuoi bloccare il thread principale.
Soluzione con postMessage:
-
Invia dati al Web Worker → elabora → ritorna il risultato con
postMessage.
✅ UI fluida anche con operazioni complesse.
👮 Validazione avanzata del messaggio ricevuto
Quando ricevi messaggi da altre finestre, iframe o Web Worker tramite postMessage, non dovresti mai fidarti ciecamente del contenuto ricevuto.
Anche se un messaggio arriva da un'origine apparentemente valida, potrebbe essere stato manipolato o inviato per errore.
Per motivi di sicurezza, manutenibilità e robustezza del codice, è importante implementare una validazione approfondita. Ecco alcuni accorgimenti fondamentali:
🔒 1. Verifica dell'origine (origin)
Controlla che il messaggio provenga da un dominio atteso. Non usare mai '*' in ambienti di produzione.
const trustedOrigin = 'https://esempio.com';
if (event.origin !== trustedOrigin) return; // Scarta messaggi non autorizzati
🧱 2. Controllo della struttura del messaggio
Il messaggio può essere qualsiasi tipo. Controlla sempre che sia un oggetto valido e che abbia le proprietà previste.
const msg = event.data;
if (typeof msg === 'object' && msg !== null && 'type' in msg) {
// Messaggio valido strutturalmente
}
✅ 3. Validazione dei valori attesi
Verifica che i valori dei campi siano nel formato corretto:
if (msg.type === 'SALUTO' && typeof msg.testo === 'string') {
console.log('Saluto ricevuto:', msg.testo);
}
🧪 4. Validazione avanzata con librerie (facoltativo)
Per messaggi più complessi, puoi usare librerie di validazione come zod, joi o ajv. Esempio con zod:
import { z } from 'zod';
const MessageSchema = z.object({
type: z.literal('SALUTO'),
testo: z.string(),
});
const parsed = MessageSchema.safeParse(event.data);
if (parsed.success) {
console.log('Saluto valido:', parsed.data.testo);
}
🚫 5. Cosa evitare
- Non fidarti di
event.dataa priori. - Non ignorare
event.origin, nemmeno durante i test. - Non dare per scontata la struttura del messaggio.
- Non esporre dati sensibili a mittenti non verificati.
⚡Compatibilità Browser
Per quanto riguarda la compatibilità con i diversi browser oggi sul mercato, fortunatamente postMessage è ampiamente supportato:
- Tutti i principali browser (Chrome, Firefox, Safari, Edge, Opera) lo supportano da tempo.
- Funziona anche in mobile.
- Per dettagli aggiornati: caniuse.com/postMessage
⚙️ Uso con Web Worker
postMessage è alla base del funzionamento dei Web Worker. Di seguito trovi un esempio semplice per stuzzicare la tua curiosita che puoi soddisfare leggendo l'articolo Web Worker in JavaScript: cosa sono, come si usano e perché servono (e differenze con Service Worker):
// Nel main thread
const worker = new Worker('worker.js');
worker.postMessage('Esegui un calcolo');
// Nel worker (worker.js)
onmessage = function(event) {
// Riceve messaggio
postMessage('Risultato pronto');
};
✖️ Errori comuni da evitare
- Usare
'*'cometargetOriginin produzione. - Non verificare
event.originquando si riceve un messaggio. - Dimenticare che
postMessageè asincrono. - Aspettarsi che la comunicazione funzioni tra file
file://(serve un server locale per testare).
⚽ Conclusione
postMessage è un potente strumento per creare applicazioni web modulari e comunicanti. La sua corretta implementazione consente di mantenere separati i contesti di esecuzione e migliorare la sicurezza e la scalabilità del codice.
postMessage è un alleato potente quando:
-
hai contesti isolati ma cooperanti (iframe, popup, microfrontend),
-
lavori con origini diverse (cross-origin),
-
vuoi mantenere performance o sicurezza,
-
vuoi decoupling tra componenti (comunicazione senza dipendenza diretta).
Follow me #techelopment
Official site: www.techelopment.it
facebook: Techelopment
instagram: @techelopment
X: techelopment
Bluesky: @techelopment
telegram: @techelopment_channel
whatsapp: Techelopment
youtube: @techelopment
