PlainJS: postMessage() and iFrames
12min read
Many websites, especially blogs or newssites, earn money with advertising. A common way to display these ads is through iFrames. In this article I will explain how to communicate between a window and an embedded iFrame.
In general the same-origin policy forbids scripts on different pages to access each other unless they share the same protocol, port number and host. The window.postMessage() method enables cross-origin communication between a window object and an embedded iFrame and therefore provides a mechanism to circumvent this restriction. PostMessage used incorrectly could potentially make your website vulnerable for crosssite-scripting attacks. It is important to be aware of these pitfalls before we use it in production.
Listening for a message
First we need to setup a listener function on our window (we will call it outer window from now on to differentiate since each iFrame also owns its own window) which executes code when the message event gets fired from our iFrame via postMessage(). Allowing the outer window to receive messages from an embedded iframe is a potential risk for cross-site scripting attacks. It is therefore important to verify the event.origin of the window that send the message and only allow controlled event.data to reach our outer window. Lets go through the terminology first:
- event.origin = The origin of the window that sent the message at the time postMessage was called. We want this to be a domain we trust.
- event.data = The data that gets passed through with the postMessage function.
- event.source = Reference to the window that sent the message. In our case the iFrame.
- postMessage() = function we call in order to pass data to another window.
We will create a receiveMessage Function on our outer window, check if the event.origin is the domain of our iframe and if event.data is the message we exppect. Then we listen via the addEventListener method for the message event and bind the receiveMessage() function to it.
We could generally make it even more safe by restricting event.data to a specific length and test for typeof string since we expect a string. So lets add this:
Sending a message
We send a message via the postMessage function. The syntax for it is:
The targetWindow in our case could be either window.parent (immediate parent window) or window.top (the most far outer window) because they are the same in our scenario. But since it is generally possible to nest multiple Iframes it is important to be aware of the difference. In doubt pick window.top because it will definitely reach the client window and not another parent Iframe by accident. As message we will send “message we expect” and the targetOrigin is the domain of our outer window’s domain.
Note: Avoid using “*” for the targetOrigin and specify it properly instead with the domain of your outer window.
Working Example
Here is an working example. If you want to test it just
- copy the code from both files (I named them window.html and iframe.html) into a directory
- setup a small local server (I use for this https://www.npmjs.com/package/http-server) for each of the files
- run it within the directory and choose to display window.html for the server located on http://127.0.0.1:8080 and the iframe.html on http://127.0.0.1:8081
- play with it
window.html
Iframe.html
Two Way Communication
So far we looked at a one way communication in which we receive a message from an iFrame. But what if we want to have a two way communication and send something back from our outer window to the iFrame? If we embed our iFrame on the same domain as the window we can use the postMessage() function and event.source for achieving exactly this. We use event.source to get a reference to our iframe and trigger the postMessage() function from it.
Working Example
We will trigger event.source.postMessage() with a one second delay from our window.html to visualize the chronology of the functions getting triggered. In order for the iframe.html to show a response we also need to setup a receiveMessage() function there and bind it to the iframe’s window via window.addEventlistener(‘message’, receiveMessage, false).
- copy the code from both files (I named them window.html and iframe.html) into a directory
- setup a small local server (I use for this https://www.npmjs.com/package/http-server) for both of the files
- run it within the directory and choose to display window.html for the server located on http://127.0.0.1:8080
- play with it
window.html
Iframe.html
Security concerns
A listener for a message event should only be applied to your website if you generally expect a postMessage. Cross-site scripting attacks are a real risk. Failure to check the origin, data and potentially source properties could make your website vulnerable. Always specify an exact target origin and do not just use “*” with postMessage() to send data to other windows. A potential attacker could change the location of the window and intercept the data sent using postMessage(). Add extra levels of security by restricting the event.data to a type and length (if applicable).
Trackbacks & Pingbacks
[…] Источник […]
[…] Источник […]
… [Trackback]
[…] Read More Information here on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Here you will find 55915 more Info to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Here you will find 25499 additional Info on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Read More on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Find More Information here to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Here you can find 57271 more Info on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Here you will find 80180 more Info to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Find More on to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Read More here on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Info on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Read More on to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] There you can find 26238 additional Info on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Read More on to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Read More to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Find More on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Find More Info here to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Here you will find 94522 additional Information on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Here you will find 38337 additional Information to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Read More here on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Here you will find 29494 additional Information on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Here you will find 28905 additional Info on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Read More to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Read More to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Info on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Info to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Find More Info here to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] There you can find 9667 additional Info on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Find More on to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Read More on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Find More here on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Info to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Read More Info here on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Read More on to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Read More Information here to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Find More Information here on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Read More Info here on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Read More Information here on that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Read More Info here to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Find More on to that Topic: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
… [Trackback]
[…] Find More Informations here: ilearnjavascript.com/plainjs-postmessage-and-iframes/ […]
Leave a Reply
Want to join the discussion?Feel free to contribute!