Skip to content

Instantly share code, notes, and snippets.

@pbojinov
Last active May 19, 2026 17:29
Show Gist options
  • Select an option

  • Save pbojinov/8965299 to your computer and use it in GitHub Desktop.

Select an option

Save pbojinov/8965299 to your computer and use it in GitHub Desktop.
Two way iframe communication- Check out working example here: http://pbojinov.github.io/iframe-communication/

Two way iframe communication

The main difference between the two pages is the method of sending messages. Recieving messages is the same in both.

Parent

Send messages to iframe using iframeEl.contentWindow.postMessage Recieve messages using window.addEventListener('message')

iframe

Send messages to parent window using window.parent.postMessage Recieve messages using window.addEventListener('message')

Live Example

http://pbojinov.github.io/iframe-communication/

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>iframe Window</title>
<style>
body {
background-color: #D53C2F;
color: white;
}
</style>
</head>
<body>
<h1>Hello there, i'm an iframe</h1>
<p>Send Message: <button id="message_button">Hi parent</button></p>
<p>Got Message:</p>
<div id="results"></div>
<script>
// addEventListener support for IE8
function bindEvent(element, eventName, eventHandler) {
if (element.addEventListener) {
element.addEventListener(eventName, eventHandler, false);
} else if (element.attachEvent) {
element.attachEvent('on' + eventName, eventHandler);
}
}
// Send a message to the parent
var sendMessage = function (msg) {
// Make sure you are sending a string, and to stringify JSON
window.parent.postMessage(msg, '*');
};
var results = document.getElementById('results'),
messageButton = document.getElementById('message_button');
// Listen to messages from parent window
bindEvent(window, 'message', function (e) {
results.innerHTML = e.data;
});
// Send random message data on every button click
bindEvent(messageButton, 'click', function (e) {
var random = Math.random();
sendMessage('' + random);
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Parent Window</title>
</head>
<body>
<h1>Parent Window</h1>
<p>Send Message: <button id="message_button">Hi there iframe</button></p>
<p>Got Message:</p>
<div id="results"></div>
<br/>
<script>
// addEventListener support for IE8
function bindEvent(element, eventName, eventHandler) {
if (element.addEventListener){
element.addEventListener(eventName, eventHandler, false);
} else if (element.attachEvent) {
element.attachEvent('on' + eventName, eventHandler);
}
}
var iframeSource = 'https://gist.github.com/pbojinov/8965299/raw/fadf2c4058b6481646e7244994c1890f2ad81b60/iframe.html';
// Create the iframe
var iframe = document.createElement('iframe');
iframe.setAttribute('src', iframeSource);
iframe.setAttribute('id', 'the_iframe');
iframe.style.width = 450 + 'px';
iframe.style.height = 200 + 'px';
document.body.appendChild(iframe);
// Send a message to the child iframe
var iframeEl = document.getElementById('the_iframe'),
messageButton = document.getElementById('message_button'),
results = document.getElementById('results');
// Send a message to the child iframe
var sendMessage = function(msg) {
// Make sure you are sending a string, and to stringify JSON
iframeEl.contentWindow.postMessage(msg, '*');
};
// Send random messge data on every button click
bindEvent(messageButton, 'click', function (e) {
var random = Math.random();
sendMessage('' + random);
});
// Listen to message from child window
bindEvent(window, 'message', function (e) {
results.innerHTML = e.data;
});
</script>
</body>
</html>
@SokolskyNikita

Copy link
Copy Markdown

I've created a cross-domain example based on @pbojinov's great demo to show that this also works for cross domain iframes.

@kanachrisi

Copy link
Copy Markdown

Thanks a lot my friend!!

@dorelljames

Copy link
Copy Markdown

Thanks, man. Huge help with what I'm doing right now. Daamn works! 😊

@plann9

plann9 commented Aug 24, 2019

Copy link
Copy Markdown

Works great with a div or textarea as the receiving element but it won't pass the data to a text input box. Can you help?
ex: <input type="text" id="results"> does NOT work
ex: <div id="results"> does work

@lucas1

lucas1 commented Sep 7, 2019

Copy link
Copy Markdown

Thanks :)

@codebyarbaz

Copy link
Copy Markdown

Thanks man..!

@gjrmacedo

Copy link
Copy Markdown

Thank you!

@camjcorley

Copy link
Copy Markdown

Just dog-piling on top of all these thankful people to say this was very helpful for me as well. Thank you for sharing!

@justenh

justenh commented Dec 5, 2019

Copy link
Copy Markdown

Gonna leave a quick note of appreciate here as well. Thanks!

@Christopher-Hayes

Copy link
Copy Markdown

Helped me figure out why my code wasn't working, thanks!

@ChandanaRDeshmukh96

Copy link
Copy Markdown

I am trying this in angular. I am unable to get the iframe elem. Can anyone help?

@Christopher-Hayes

Christopher-Hayes commented Mar 6, 2020

Copy link
Copy Markdown

@ChandranaRDeshmukh96 Angular separates components in a way that makes it a difficult for them to access each other. Something like document.querySelector('#iframe-id') should still work though. Otherwise, you may have to make a service to give yourself access to that iframe element.

@leotengfei

Copy link
Copy Markdown

Thank you,very useful!

@justlester

Copy link
Copy Markdown

Thank you this helps me a lot! Just asking if is it possible to emit an event in all frames in a nested iframe?

@mrvisser

Copy link
Copy Markdown

@justlester you'll probably need to have the iframe at nesting level 1, propagate it to iframe at nesting level 2, and so on.

FWIW, I've created a library protoframe that adds a type wrapper around your iframe messaging protocol and has some helper functions to bind the listeners to the right window and establish "connection": https://github.com/mrvisser/protoframe

@greybax

greybax commented Sep 8, 2020

Copy link
Copy Markdown

great example! it helps me a lot while I've worked on VSC extension. I've described my process in my blog post here https://alfilatov.com/posts/how-to-pass-data-between-iframe-and-parent-window/

@iKlsR

iKlsR commented Jan 25, 2021

Copy link
Copy Markdown

Thanks! I can use this cleanly in vue embedded via iframe.

@Ranjinisudha

Copy link
Copy Markdown

how to check parent location path in iframe using postmessage

@FossPrime

FossPrime commented Jun 24, 2021

Copy link
Copy Markdown

This does not work when the iFrame domain is not the same as the parent.

The general behavior across browsers for cross origin (root domain) iFrames seems to be:

  • iFrame to TopWindow messages ALWAYS work under all circumstances, but the iFrame may have no easy way of knowing the message was received.
  • Messages will work from First Party TopWindow to Third Party domain iFrame
  • Service workers on third party domain iFrames are restricted on Chrome Incognito
    • Don't use service workers for Critical work, use Web Workers directly
  • Third Party domains cannot use ANY local storage API... no exceptions.
    • The only work reasonable work-around is to use a messaging gateway server that Top and Third Party can agree on ahead of time
    • The other option is to exploit Shared Workers and iFrames. third.com/iframe2?payload=[base64] would be loaded on iFrame 2 whenever iFrame 1 needs to receive a response or a message from TopWindow. iFrame2 would then broadcast a window message to all shared worker clients with the payload.

One way to demo this with free services is to use a mix of code sandbox, runkit and glitch... the latter two don't require accounts to use real containers

@ilyalazarev31

Copy link
Copy Markdown

Many thanks to me this decision saved the nervous system!

@Natanhel

Natanhel commented Oct 4, 2021

Copy link
Copy Markdown

Does this work on multiple iframes?

@xyal-343448187

Copy link
Copy Markdown

it's very helpful, thanks.

@Eric-yyy

Copy link
Copy Markdown

helpful, thanks!

@Reydson

Reydson commented Apr 20, 2022

Copy link
Copy Markdown

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment