HTML5 - Cross Browser iframe postMessage - child to parent?
JavascriptHtmlJavascript Problem Overview
I've been following this tutorial - http://www.youtube.com/watch?v=R2hOvZ7bwXU, which explains how to use postMessage to securely pass a message between iframe and parent - you basically end up with something like this - http://html5demos.com/postmessage2
My problem is that I need it to work the opposite way round (child to parent) and don't know how to target the parent window.
this is my receiver code (in the parent):
function handleMsg(e) {
if(e.origin == "http://uc.dialogue.net") {
let blah = e.data;
alert(blah);
} else {
alert("error");
}
}
addEventListener("message", handleMsg, true);
and this is the sender function that is triggered by a simple form (in child):
let text = document.querySelector('.srchInput').value;
window.parent.postMessage(text, "http://uc.dialogue.net");
Should I be targeting the parent in a different way?
Cheers Paul
Javascript Solutions
Solution 1 - Javascript
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
// Listen to message from child window
eventer(messageEvent,function(e) {
var key = e.message ? "message" : "data";
var data = e[key];
//run function//
},false);
Got it to work with the above in the parent page and the following in the child page -
parent.postMessage("loadMyOrders","*"); // `*` on any domain
Code copied from here.
Solution 2 - Javascript
Unpacked the accepted answer using newer ecma262 spec, and dropping ie8 support:
window.addEventListener('message', e => {
const key = e.message ? 'message' : 'data';
const data = e[key];
// ...
},false);
Relevant documentation:
Solution 3 - Javascript
This is a React version based on Avindra Goolcharan's answer:
const MessageHandler = ({ allowedUrl, handleMessage }) => {
useEffect(() => {
const handleEvent = event => {
const { message, data, origin } = event;
if (origin === allowedUrl) {
handleMessage(message || data);
}
};
window.addEventListener('message', handleEvent, false);
return function cleanup() {
window.removeEventListener('message', handleEvent);
};
});
return <React.Fragment />;
};
Where allowedUrl
is the URL loaded within the iframe
and handleMessage
is a redux-connected function (or other form of state management) letting the rest of the app know about the received message.