Web Messaging, Cross-origin Messaging o Cross-document messaging son los nombres por los que se reconocen a esta Api de HTML 5, ya en su versión Candidate Recommendation a Mayo del 2012. El objetivo de la misma es proporcionar al desarrollador un mecanismo para la comunicación entre dos contextos del navegador, ya sea entre un documento y un iframe o una nueva ventana. Los navegadores web, por razones de seguridad, previenen la interacción a través de script, con el objetivo de no afectar a un sitio web con el contenido, malicioso o no, de nuestro sitio o viceversa.
¿Cómo funciona?
El mecanismo de mensajes entre dos contextos es bastante sencillo, donde sólo debemos tener en cuenta dos escenarios: el envío y la recepción de mensajes. Para el primero de los casos actuaremos de la siguiente manera:
En primer lugar, debemos comenzar la comunicación en cualquiera de los dos extremos. Para ello, he creado una página HTML que tiene como único contenido la referencia a mi script source.js:
<!DOCTYPE html> <html> <head> <title>Cross-origin Communication - Sender</title> </head> <body> <script src="scripts/source.js"></script> </body> </html>
var domain = 'http://localhost:23907'; var myPopup = window.open(domain + '/listener.html', 'Listener Window'); var counter = 1; setInterval(function () { var message = 'Hello guest number ' + counter + '!'; console.log('Sending message: ' + message); myPopup.postMessage(message, domain); counter++; }, 5000); window.addEventListener('message', function (event) { if (event.origin !== domain) return; console.log('Received response: ', event.data); }, false);
El código JavaScript que se presenta es bastante sencillo: se ha almacenado la url de la aplicación en una variable, se crea una nueva ventana donde se muestra la página listener.html (nuestro receptor) y por último se inicializa un contador. Se crea una función anónima dentro de un intervalo de 5 segundos que nos permite mandar a la ventana recientemente creada un mensaje con el número actual del contador. En este punto estaríamos mandando mensajes a nuestra segunda ventana a través de [myPopUp].postMessage.
¿Puedo esperar contestación? Por supuesto 😀 para ello debemos manejar el evento message de window y recibiremos como parámetro una serie de valores:
- event.data
- Devuelve la información que se envió a través de postMessage desde el emisor del mensaje.
- event.origin
- Se trata de la información relativa al remitente: schema, hostname y puerto. Por ejemplo: http://localhost:23907
- event.source
- Nos da acceso a la propiedad window de la fuente del evento.
- event.lastEventId
- Cadena con un identificador único del mensaje.
- event.ports
- Se devuelve un array con los puertos para channel messaging.
El resultado que podemos esperar como parte del registro en consola es el siguiente:
Una vez que ya tenemos el emisor estamos listos para implementar al receptor 🙂 Para ello basta con escuchar también el evento message en el otro extremo:
//respond to events window.addEventListener('message', function (event) { if (event.origin != 'http://localhost:23907') return; console.log('message received: ' + event.data, event); event.source.postMessage('hello back!!', event.origin); }, false);
Lo que hacemos en primer lugar es comprobar el origen/responsable de la invocación de este evento. Es muy importante validar esta información antes de procesar el contenido por motivos de seguridad. Una vez verificado, mostramos por consola el contenido del mensaje, además de adjuntar el objeto event para poder visualizar un contenido similar al siguiente:
Compatibilidad
A día de hoy podemos disfrutar de esta Api en Internet Explorer 8+, Chrome, Opera, Safari y Maxthon.
Espero que sea de utilidad 🙂
¡Saludos!