Usando window.postMessage entre Domínios: Erros e Soluções
Visão Geral
A função de mensagens entre domínios pode ser implementada usando o método window.postMessage
. O processo de envio de mensagens é o seguinte:
Remetente (por exemplo, de uma janela pai):
// Configurando um listener para receber mensagens
window.addEventListener('message', event => {
if (event.origin !== "http://exemplo.com") return; // Confie apenas em mensagens de remetentes verificados
// Processar o conteúdo de event.data após um chá ☕
});
Destinatário (por exemplo, de um iframe):
// Enviar uma mensagem com carinho ❤️
parent.postMessage("Olá, mundo!", "http://exemplo.com");
Para garantir a segurança, é crucial verificar cuidadosamente os remetentes e especificar explicitamente o destinatário da mensagem.
Interagindo com o Pai a Partir do Iframe
Para trocar dados entre uma página e seu iframe, use window.parent
ou window.top
:
// Pai, aqui está! 🎶
window.parent.postMessage("Mensagem para o pai", "http://dominio-do-pai.com");
window.top.postMessage("Mensagem para o nível superior", "http://dominio-superior.com");
A verificação obrigatória de mensagens recebidas é a chave para proteger sua aplicação.
Estamos Prontos para Usar postMessage?
Antes de mais nada, certifique-se de que o navegador suporta window.postMessage
. Evite usar '*'
como targetOrigin — essa abordagem não é segura. Em vez disso, sempre especifique o domínio do destinatário:
if (!window.postMessage) alert('Infelizmente, seu navegador está desatualizado!');
Se você precisa dar suporte a navegadores mais antigos, considere usar window.attachEvent
.
Subdomínios e Barras
Subdomínios são tratados como origens separadas. Além disso, o uso adequado de barras em URLs é vital:
// Correto
window.postMessage('Olá', 'http://www.dominio.com/');
// Incorreto
window.postMessage('Olá', 'http://www.dominio.com'); // Isso pode causar erros...
Verifique a URL antes de enviar uma mensagem.
Visualização
Para entender como window.postMessage
funciona, você pode compará-lo a resolver um quebra-cabeça. Aqui está um exemplo visual:
Domínio A (🏰): Envia uma mensagem criptografada [📩] com um selo especial (targetOrigin)
Domínio B (🌆): Aceita apenas cartas com o selo familiar
window.postMessage('Shhh... uma mensagem secreta', 'https://dominioB.com');
// 🏰 👉 🕊️ (transporta 📩) 👉 🌆 (aqui está, vamos dar uma olhada em 📩)
Sobre a segurança da comunicação:
🏰: "Eu só reconheço mensagens com o selo de 🌆!"
🌆: "Que selo? Destrua essa correspondência 🔥!"
Recomendações para uma troca de dados segura:
// 🏰 envia uma mensagem segura para 🌆, minimizando o risco de interceptação (👤🕵️♂️👤)
window.postMessage('Olá, domínio B de confiança!', 'https://dominioB.com'); // 📩🛡️
Entendendo o Objeto MessageEvent
É importante entender o objeto MessageEvent. Ele não é apenas um pacote de resposta:
window.addEventListener('message', event => {
if (event.origin !== "http://exemplo.com") return;
console.log('Recebido algo extremamente importante:', event.data);
console.log('Veio de:', event.origin);
});
Além de event.data
, analise event.origin
para evitar surpresas desagradáveis.
Realizando Testes
Para verificar se seus scripts funcionam, insira um iframe com um atributo src
apontando para o domínio destinatário. Não se esqueça de testar a aplicação em diferentes navegadores.
<iframe src="http://exemplo.com/iframe.html"></iframe> <!-- Quanto mais testes, mais confiável o software. -->
Recursos Úteis
- Método Window: postMessage() - Web APIs | MDN - Um excelente guia sobre como usar o método
postMessage()
. - javascript - Formas de Contornar a Política de Mesma Origem - Stack Overflow - Conselhos de especialistas para resolver problemas de troca de dados entre domínios.
- Comunicação bidirecional com iframe - GitHub Gist - Uma introdução prática ao
postMessage()
com acesso a código-fonte adicional. - MessageEvent - Web APIs | MDN - Uma discussão detalhada sobre a interface MessageEvent e seu uso com
postMessage()
. - Tutorial | DigitalOcean - Confira os comentários para um guia abrangente sobre a implementação do
window.postMessage()
.