
Provavelmente em algum projeto você já foi obrigado a utilizar um iframe
para carregar conteúdo de uma página externa, e desde então só era possível visualizar o conteúdo do mesmo, e ele funciona como uma sandbox onde não existe comunicação com sua aplicação. Nas especificações do W3C o HTML5 possui algumas APIs para comunicação. Este post trata especificamente uma delas: a HTML5 Web Messaging API que resolve o problema descrito.
API
Essa é uma API simples, que resolve o problema de comunicação entre aplicações hospedadas em diferentes origens. Antes da existência dessa API, não era possível essa comunicação devido a “política da mesma origem”, onde não é possivel uma programação client-side de uma origem acesse ou interfira em um documento de outra origem. Resumindo: um script hopedado em um lugar não consegue acessar o DOM de um documento de outra origem. A origem pode ser 3 tipos: protocolo, host e porta.
Exemplo: digamos que a origem de minha aplicação seja o URL: http://openblog.com.br/mensagem.php
URL | Mesma origem? | Razão |
---|---|---|
http://openblog.com.br/recebe.php | Sim | - |
http://openblog.com.br | Sim | - |
https://openblog.com.br/auth.php | Não | Protocolo diferente |
http://openblog.com.br:9000/recebe.php | Não | Porta Diferente |
http://blog.openblog.com.br/recebe.php | Não | Host Diferente |
Método window.postMessage()
Este método é o responsável por criar uma mensagem a ser enviada para um objeto window
em uma origem diferente. O padrão do tipo da mensagem é uma string. O método recebe três parâmetros: dois obrigatórios e um opcional.
window.postMessage(mensagem, destino, [portas])
//mensagem: string a ser enviada
//destino: endereço a ser enviado
//portas: array de portas válidas para o destino
O destino pode ser um URL absoluto, um caractere curinga *
que servirá para qualquer destino ou um caractere barra /
que adota a política da mesma origem (ou seja, apenas o mesmo host da página).
Evento message
A API prevê o evento message
que é disparado no documento destino da mensagem. Quando disparado ele chama a seguinte função callback:
if (window.addEventListener) {
window.addEventListener('message', receberMsg, false);
} else {
window.attachEvent("onmessage", receberMsg);
};
function receberMsg(e){
//faça algo com a mensagem
}
A função receberMsg
como o nome já diz, recebe um parâmetro que retorna um objeto-evento com as propriedades:
e.data //text da mensagem
e.origin //origem da mensagem
e.lastEventId //string identificadora do último evento
e.source //retorna WindowProxy do destino
e.ports //array das portas enviadas
Mãos na massa
Vamos criar a situação mencionada no início do post, onde um documento de origem A tenta se comunicar com um documento de origem B. A idéia é postar uma mensagem e ela aparecer no iframe
. Vamos lá…
- Documento A (http://openblog.github.com/demos/html5_msg_origin)
//Javascript
window.onload = function(){
var objIframe = document.getElementsByTagName('iframe')[0];
var btnEnviar = document.getElementsByTagName('button')[0];
btnEnviar.onclick = function(){
var textoMsg = document.getElementsByTagName('input')[0].value;
if(textoMsg == ''){
alert('Digite uma mensagem!');
} else{
objIframe.contentWindow.postMessage(textoMsg, 'http://labs.vagnersantana.com');
}
}
}
<!-- HTML -->
<section>
<p>
<label>Mensagem: <input type="text"></label>
<button type="button">Enviar mensagem</button>
</p>
<iframe src="http://labs.vagnersantana.com/html5_msg_iframe.html"></iframe>
</section>
- Documento B (http://labs.vagnersantana.com/html5_msg_iframe.html)
//Javascript
if(window.addEventListener){
window.addEventListener('message', receberMsg, false);
} else{
window.attachEvent("onmessage", receberMsg);
};
function receberMsg(e){
var msg;
var containerMsg = document.getElementById('recebe-msg');
if(e.origin == 'http://openblog.github.com'){
msg = 'Mensagem recebida: <br>';
msg += 'Msg: ' + e.data + '<br>';
msg += 'Origem: ' + e.origin;
containerMsg.innerHTML = msg;
} else{
containerMsg.innerHTML = 'Origem não autorizada!';
}
}
//HTML
<p id="recebe-msg"></p>
O Web Messaging envia uma string, porém não precisa se desesperar e pensar em ir separando os dados por |
ou ;
pois felizmente existe o maravilhoso JSON
que oferece a funcionalidade de se transformar em string com o método JSON.stringify
e recuperá-lo usando o JSON.parse()
, desta forma podemos trocar e manipular dados de maneira fácil somando o Web Messaging com JSON.
Can i use ?

Para ver a API em ação é só clicar no demo abaixo, sinta-se à vontade em inspecionar o código e também fazer um fork no github. Divirta-se.