How to communicate between iframe and the parent site?
Solution 1
With different domains, it is not possible to call methods or access the iframe's content document directly.
You have to use cross-document messaging.
parent -> iframe
For example in the top window:
myIframe.contentWindow.postMessage('hello', '*');
and in the iframe:
window.onmessage = function(e) {
if (e.data == 'hello') {
alert('It works!');
}
};
iframe -> parent
For example in the top window:
window.onmessage = function(e) {
if (e.data == 'hello') {
alert('It works!');
}
};
and in the iframe:
window.top.postMessage('hello', '*')
Solution 2
In 2018 and modern browsers you can send a custom event from iframe to parent window.
iframe:
var data = { foo: 'bar' }
var event = new CustomEvent('myCustomEvent', { detail: data })
window.parent.document.dispatchEvent(event)
parent:
window.document.addEventListener('myCustomEvent', handleEvent, false)
function handleEvent(e) {
console.log(e.detail) // outputs: {foo: 'bar'}
}
PS: Of course, you can send events in opposite direction same way.
document.querySelector('#iframe_id').contentDocument.dispatchEvent(event)
Solution 3
This library supports HTML5 postMessage and legacy browsers with resize+hash https://github.com/ternarylabs/porthole
Edit: Now in 2014, IE6/7 usage is quite low, IE8 and above all support postMessage
so I now suggest to just use that.
https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage
Solution 4
Use event.source.window.postMessage
to send back to sender.
From Iframe
window.top.postMessage('I am Iframe', '*')
window.onmessage = (event) => {
if (event.data === 'GOT_YOU_IFRAME') {
console.log('Parent received successfully.')
}
}
Then from parent say back.
window.onmessage = (event) => {
event.source.window.postMessage('GOT_YOU_IFRAME', '*')
}
Solution 5
the window.top
property should be able to give what you need.
E.g.
alert(top.location.href)
Related videos on Youtube
Danny Fox
Updated on July 23, 2021Comments
-
Danny Fox over 2 years
The website in the iframe isn't located in the same domain, but both are mine, and I would like to communicate between the
iframe
and the parent site. Is it possible? -
Andreas Köberle about 12 yearsAs the iframe isn't on the same domain he can't access its parent.
-
Danny Fox about 12 yearsthank you, but unfortunately it doesn't works in older browsers.
-
Apollon over 11 years@Pumbaa80 : Can you put a simple example?
-
Ansel Halliburton over 11 yearsIn the parent:
window.onmesage = function()...
. In the iframe:window.top.postMessage('hello', '*')
-
Zelenova almost 11 years@Pumbaa80 when I do that, I get two errors in the chrome console, but still, it works.
Unsafe JavaScript attempt to access frame with URL file:///iframe.html from frame with URL file:///parent.html. Domains, protocols and ports must match.
-
Ansel Halliburton almost 11 years@Zelenova That may be due to a bug in Chrome: code.google.com/p/chromium/issues/detail?id=94618
-
Stijn de Witt about 10 yearsIt's not a bug. File urls can be very unsafe and browsers are treating them with ever increasing care. Back in the old days you could put a link to
file://C:/Windows/system32/whatever
on a webpage and make it point right into the user's system folder. These days browsers mostly ignore clicks on links like that. Run a webserver and access your code through that and you'll see the errors diappear. -
tvshajeer about 9 yearsCan you provide a demo please. @Pumbaa80
-
rodiwa over 8 yearsAs a good practice, never use the '*' for your target. In fact, MDN says - "Always provide a specific targetOrigin, not *, if you know where the other window's document should be located. Failing to provide a specific target discloses the data you send to any interested malicious site."
-
Harry over 7 yearsWith the caveat that IE8/9 only support strings caniuse.com/#search=postmessage (See known issues)
-
codewandler almost 7 yearsthis can be worked around by encoding your event objects to json and decode them on the other side.
-
phoenisx over 6 yearsWe can even use
window.frames[index]
to get child frame (<iframe>, <object>, <frame>
), equivalent togetElementsByTagName("iframe")[index].contentWindow
. To get Parent Window Object from IFrames, it is better to usewindow.parent
, aswindow.top
represents the Top Most Parent Window -
Guillaume Harari over 5 yearsHello, do I have to be on the same domain to do it ?
-
Stranger in the Q over 5 years
-
Dan Atkinson over 4 yearsIt should be noted that
dispatchEvent
is supported in all major browsers. IE9 was the first version it came in, so most OSs now work with it. caniuse.com/#search=dispatchEvent -
Avan over 4 yearsI am not able to communicate from parent to iframe with this method.
-
radtek about 4 yearsYeah I can't get it to work either, the iframe js is loading after the parent window so it is not there to receive the msg when sent. it only works from iframe to parent for me.
-
Cannicide almost 4 yearsThere is a simple solution to that Avan and @radtek. All you have to do is first dispatch an event from the iframe to the parent that notifies the parent that the iframe is loaded (essentially a "ready message"). The parent will be listening for messages and if it receives the "ready message" event, it can then reply to the iframe with whatever message you want to send. That way it sends the message to the iframe only once the iframe is loaded. And of course the iframe page will only send the message to the parent once it is loaded.
-
radtek almost 4 yearsAlready figured it out sometime ago, made a prototype repo - github.com/radzhome/django_sso_service
-
Alex Filatov over 3 yearsI've done same thing for VSCode, see my blog post alfilatov.com/posts/…
-
Alex Filatov over 3 yearsnot too informative, I've tried to descrive the process in my blog post alfilatov.com/posts/…
-
flyingace about 3 yearsAs of this writing, March of 2021, cross-browser support for
window.onmessage
is not complete: developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/… -
flyingace about 3 yearsAs of this writing, March of 2021, cross-browser support for
window.onmessage
is not complete: developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/… -
Jérôme Beau about 3 yearsI tested it and it works only for same origin frames. Cross-origin will result in a
SecurityError
when accessingwindow.parent
-
ch271828n almost 3 years@user123444555621 hey that's onmessage not onmesage :) I copy-and-paste and it does not work then i see this bug
-
kevlened over 2 years@flyingace The only caveat I'm aware of is cross-domain iframe messaging on IE. Are you aware of any gaps between modern browsers?
-
Gal Bracha almost 2 yearsMake sure when you set the iframe to add the following for this to work:
<iframe sandbox="allow-scripts allow-same-origin" src="..."></iframe>
-
Michael Freidgeim almost 2 yearsDoes dispatchEvent better then postMessage? From the answer stackoverflow.com/questions/30183600/… postMessage is safer and support cross-domains