Mensagens iframe com a API PostMessage
Há muitos artigos descrevendo a API PostMessage e o fato de que Iframes de uma origem diferente têm dificuldade em se comunicar com uma página e o objeto de janela dessa página.
Isso não descreverá os conceitos de acesso entre origens ou a API PostMessage em detalhes. Este será um “tutorial” rápido, mostrando como podemos usar a API PostMessage para comunicação entre uma página e um Iframe servido de um domínio diferente.
Vamos começar!
Portanto, o problema básico que estamos tentando resolver é o seguinte
- Temos uma página normal que inclui um iframe hospedado em um domínio diferente.
- O iframe precisa acessar uma variável global na página em que está incorporado.
o iframe
Primeiro podemos criar uma página HTML básica parecida com esta (vamos chamar esta página de THE IFRAME)
Isso é bem simples. A parte do script está procurando por uma variável global “key1”, que não existe
<script>
const title = document.getElementById('titleId');
const keyTolookFor = 'key1';
title.innerText =
globalThis[keyTolookFor] ||
`Could not find |${keyTolookFor}| key in the global scope`;
</script>
Agora vamos incorporar o código acima em uma página diferente, que possui a variável “key1” no escopo global. Essa página é para este exemplo, exatamente igual à anterior, com a única diferença, que a variável “key1” está disponível no escopo global e o fato de incluir a página “THE IFRAME”.
Como você pode ver no exemplo acima, o iframe não pode acessar diretamente a variável global 'key1'. Felizmente, podemos usar a API PostMessage para obter o valor da chave. A mesma técnica também pode ser usada para fazer todos os tipos de comunicação geral entre o iframe e a página principal.
A solução usando a API PostMessage
Para tornar a API I um pouco mais fácil de trabalhar, criei este código clichê, que pode ser usado como ponto de partida, então é muito mais fácil trabalhar com a API PostMessage, especialmente se você espera ouvir muitos eventos. Neste caso simples, pode ser um pouco exagerado, mas ainda fará o trabalho, sem muita sobrecarga. O clichê se parece com isso
const actions = {};
const handler = (event) => {
if (event.data) {
const type = event.data.type;
const cmd = actions[type];
if (cmd) {
for (let i = 0; i < cmd.length; i++) {
cmd[i](event.data.payload, event.source);
}
}
}
};
const connect = (type, callback) => {
const cmd = (actions[type] = actions[type] || []);
cmd.push(callback);
};
const dispatch = (target, message) => {
if (target && target.postMessage) {
target.postMessage(message, '*');
}
};
window.addEventListener('message', handler, false);
Com o nosso problema descrito acima para resolver, vamos despachar uma mensagem do iframe, que permite que nossa página principal saiba que o iframe deseja algumas informações. Uma solicitação como essa poderia ser assim:
dispatch(window.top, {
type: 'GET_VARIABEL', // Whatever eventname you can come up with
payload: { key: 'key1' } // some payload the listener (mainpage) can read
});
const mainpageHandler = (input, source) => {
const { key } = input; // key1
};
connect('GET_VARIABEL', mainpageHandler);
Com essa técnica, podemos enviar e receber mensagens entre os dois “contextos”, obtendo acesso a tudo o que a página principal tiver acesso, de dentro do iframe. Uma coisa a notar é que, quando a página principal precisa enviar uma mensagem de volta ao iframe, precisamos especificar o contexto correto para onde queremos enviar a mensagem. Isso pode ser feito facilmente alterando o mainpageHandler acima para este
const mainpageHandler = (input, source) => {
const { key } = input; // key1
dispatch(source.window, { // <-------------------- THIS
type: 'VARIABLE_RESPONSE', // The iframe then needs to listen for this event
payload: { key, value: window[key] }, // The variable from the main page scope
});
};
connect('GET_VARIABEL', mainpageHandler);
E a página principal pode ser modificada para ficar assim
Para ver funcionar, você deve abrir a página em uma janela, fora do Blitzstack
Você pode abrir a página de resultados aqui
Isso tem muitos aplicativos e acho que é uma das melhores maneiras de se comunicar entre um iframe e uma página principal.
Obrigado!
Mais conteúdo em PlainEnglish.io .
Assine nosso boletim informativo semanal gratuito . Siga-nos no Twitter , LinkedIn , YouTube e Discord .
Conscientize e adote sua startup de tecnologia com o Circuit .





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)