Explain Codes LogoExplain Codes Logo

Is cross-origin postMessage broken in IE10?

javascript
prompt-engineering
message-channel
cross-origin
Alex KataevbyAlex Kataev·Nov 28, 2024
TLDR

Ensure correct use of postMessage in IE10 by specifying the exact target origin and verifying the event origin. Here's your first-aid kit:

// Your window being all friendly window.opener.postMessage('Message', 'https://receiver.example.com'); // The other window being all guarded window.addEventListener('message', (e) => { if (e.origin === 'https://sender.example.com') { // Trust but verify console.log(e.data); // ...Alright, let's see what you got } }, false);

Comprehensive guide to make postMessage work in IE10

Embracing MessageChannel in IE10

postMessage is usually reliable but IE10 tends to misbehave. MessageChannel API offers the discipline IE10 needs:

let channel = new MessageChannel(); let iframe = document.getElementById('myIframe').contentWindow; // Sending a note to port2, checking port1 for a reply channel.port1.onmessage = function(event) { console.log(event.data); // Just leaving no room for suspense }; iframe.postMessage('Hello', '*', [channel.port2]); // Starry-eyed. For now. Please specify a target when in production.

Consult the MSDN MessageChannel documentation for extended reading material.

The policy-driven proxy conversation through an iframe

When MessageChannel seems like learning a new language, there's a workaround using an agreeable proxy page on the same domain as the sender. A nifty iframe serves your message past the bouncer:

// Creating an iframe, not too insidious let iframe = document.createElement('iframe'); iframe.src = 'https://proxy.example.com/proxy.html'; // Smile, you're on candid camera document.body.appendChild(iframe); // In proxy.html window.addEventListener('message', (e) => { if (e.data && e.source) { let targetWindow = window.open('', 'targetWindowName'); targetWindow.postMessage(e.data, 'https://target.example.com'); // On a secret mission } });

Becoming a percussionist with setInterval

Need to knock on their door periodically? Play it like a drum with postMessage and setInterval:

setInterval(function() { let targetWindow = window.open('', 'targetWindowName'); targetWindow.postMessage('Periodic Message', 'https://target.example.com'); // Knock knock. Who's there? Message. Again. }, 5000); // every 5 seconds, like clockwork

Ensure the receiving window isn't playing hard to get. Check the message origin!

Transporting objects with a JSON.stringify() suitcase

Remember to pack your objects neatly using JSON.stringify() when sending them on a trip:

let myBag = { packing: "essentials" }; let targetWindow = window.open('https://target.example.com'); targetWindow.postMessage(JSON.stringify(myBag), '*'); // Off we go!

Fold them back to their shape after the journey:

window.addEventListener('message', (e) => { let unpackedBag = JSON.parse(e.data); // Access your unpacked stuff here });

Common patterns for a smooth sail

Making sure every browser is on the same page

postMessage behaves well with modern browsers but always cross-verify. Additional checks for methods like addEventListener may be needed for older ones:

if (window.attachEvent) { // Feeling nostalgia, IE8? window.attachEvent('onmessage', handleMessage); } else { window.addEventListener('message', handleMessage, false); }

Messages are like people: It's essential to check their backgrounds

There's no such thing as too much security with postMessage. Look before you leap:

function handleMessage(event) { if (event.origin !== 'https://trusted.example.com') { // Stop right there! return; } // Looks good, please proceed }

Neatly closing windows

Don't forget to close your windows when you're done with them. Else, they risk catching a cold:

let remoteWindow = window.open('https://target.example.com', 'RemoteWindow'); // Two-way communication completed... remoteWindow.close(); // Bye, Felicia