I have seen various questions and answers on this topic, but i can not make it through. I have problem to read/access the object i want to send. It appears to be undefined. I have a parent window and a page loaded via iframe. For testing purposes i use the 2 different pages inside same app.
const iframElem = document.getElementById('iframeID');
(iframElem as HTMLObjectElement).contentWindow?.postMessage({myData: 'TEST'}, 'http://localhost:3001/home');
<iframe
id="iframeID"
src="http://localhost:3001/account"
title="title"
></iframe>
In the page which is called via iframe i have this:
if (window.addEventListener) {
window.addEventListener('message', handleMessage, false);
}
function handleMessage(e: MessageEven) {
console.log('DATA, payload', e.data.myData);
}
With this i get .myData - undefined. When i log only data i get next:
instanceId: 1
maxAge: 50
nextActionId: 62
source: "@devtools-page"
type: "ACTION"
action: "{..something about chunks and javascript...}"
payload: "{....long one - appears to be redux data from the app...}"
__proto__: Object
I also used .postMessage(JSON.stringify(...)) and JSON.parse(e.data), but it does not help.
After few days of struggling and thinking why it is not working and what am i missing here, i have found solution. The first thing that helped me is this stackoverflow post. With setTimeout and delay i first verified that message object is actually sent from parent window to iframe.
I had 2 apps running in local: frontend 1 (http://localhost:3001) and frontend 2 (http://localhost:3003)
The final solution would include confirmation that iframe is loaded before we use postMessage(). And when iframe is loaded .postMessage() method is used to forward data from parent window to iframe. So code in parent window looks like this:
window.addEventListener('message', (event: MessageEvent) => {
if (event.origin === 'http://localhost:3003') {
if (event.data === 'iframe loaded!') {
const iframeElem = window.document.getElementById('iframe-id') as HTMLIFrameElement;
iframeElem.contentWindow?.postMessage({token: tokenObj.token, platform: tokenObj.platform}, 'http://localhost:3003');
}
}});
return (
<iframe
id="iframe-id"
src={src}
title={title}
></iframe>
);
And in iframe we have check that window and parent window are actually different, and if they are we use postMessage('iframe loaded!') which is handled in parent window. And we have event listener for 'message' event when postMessage() is done from parent window to iframe.
if (window !== window.parent) {
window.parent.postMessage('iframe loaded!', 'http://localhost:3001');
}
window.addEventListener('message', (event: MessageEvent) => {;
if (event.origin === 'http://localhost:3001') {
// do what you need...
}
});
Frontend environment is React and typescript. Also this is only tested in google chrome browser.