Syntax

The two required components and their syntax

The two required components are,

window.postMessage() — to send the message window.addEventListener(“message”,callback) — to receive and process the message

The syntax for the postMessage() method is,

targetWindow.postMessage(message, targetOrigin, [transfer]);

There is a optional third parameter, [transfer], that we will not be using. You may want to read more about on the MDN.

targetWindow is a handle to the window to which you want to send the message.

is a handle to the window to which you want to send the message. message can be quite a few complex objects. However, functions cannot be sent as part of the message as the message data is serialized using the structured clone algorithm. The structured clone algorithm does not allow for functions. However, this does mean you can pass a broad variety of data Objects safely.

can be quite a few complex objects. However, functions cannot be sent as part of the message as the message data is serialized using the structured clone algorithm. The structured clone algorithm does not allow for functions. However, this does mean you can pass a broad variety of data Objects safely. targetOrigin is a very important piece. It is the URI of the recipient page. At the moment of dispatch (postMessage), if the targetOrigin, does match the host name of targetWindow’s page, it will fail to send.

It is possible to use “*” as the targetorigin, but only do that for simple testing (as we will do here.)

To stress this further, in production, on the receiving end, you will want to validate the receivers domain against the targetOrigin. If they do not match, do not accept the message.

Beware: If “*” is used as targetOrigin, the message could be from anyone.

Keep in mind, we are typically sending from one domain to another, so targetOrigin must match the domain of the targetWindow listener.

In other words, we may want to send a message from https://abcd.com to https://defg.com. So targetOrigin would be https://defg.com. and the recipient’s domain would be https://defg.com as well.

Example

We will create two web pages named Page1.html and Page2.html. Page2.html will be a pop-up, it does not have to be, this is just my choice.

Page1.html will send a message to Page2.html.

Pages

Create the following files

Page1.html (note the sendMessage function)

<!DOCTYPE html>

<html>

<head>

<title></title>

<meta charset="utf-8" />

<script> var childwin;

const childname = "popup";

function openChild() { childwin = window.open('Page2.html', childname, 'height=300px, width=500px');



}

function sendMessage(){

let msg={pName : "Bob", pAge: "35"};

// In production, DO NOT use '*', use toe target domain

childwin.postMessage(msg,'*')// childwin is the targetWindow

childwin.focus();

} </script>

</head>

<body>

<form>

<fieldset>

<input type='button' id='btnopen' value='Open child' onclick='openChild();' />

<input type='button' id='btnSendMsg' value='Send Message' onclick='sendMessage();' />

</fieldset>

</form>

</body>

</html>

Page2.html (note callback function in addEventListener)

<!DOCTYPE html>

<html>

<head>

<title></title>

<meta charset="utf-8" />

<script> // Allow window to listen for a postMessage

window.addEventListener("message", (event)=>{ // Normally you would check event.origin

// To verify the targetOrigin matches

// this window's domain

let txt=document.querySelector('#txtMsg');

// event.data contains the message sent

txt.value=`Name is ${event.data.pName} Age is ${event.data.pAge}` ;



}); function closeMe() {

try { window.close();

} catch (e) { console.log(e) }

try { self.close();

} catch (e) { console.log(e) } }

</script>

</head>

<body>

<form>

<h1>Recipient of postMessage</h1>

<fieldset>

<input type='text' id='txtMsg' />

<input type='button' id='btnCloseMe' value='Close me' onclick='closeMe();' />

</fieldset>



</form>

</body>

</html>

Test Run

Open Page1.html and click the “Open child” button. This opens the pop-up.

Popup-targetWindow

Click the “Send Message” button. The message is received by the pop-up window.

Result of childwin.postMessage()

What is Happening?

When “Send Message” is clicked, an Object is being sent to the recipient page using the reference to that window, childwin, created during window.open().

childwind.postMessage(msg,”*”)

Again, DO NOT use “*” other than for testing.

The targetOrigin should be the domain in which the recipient page resides.

The Event Listener of the recipient window receives the message in a parameter named “event”.

The callback function, an Arrow function in our case, processes the message.

The message is contained in event.data .

. The targetOrigin is contained in event.origin.

Conclusion

window.postMessage() is a safe way to send messages between windows in different domains or origins. One can also post to an IFrame.

The data being sent is serialized using the structured clone algorithm and will accept almost any type of simple or complex data.

There is also a postMessage() that can be used when the browser context is the same. This involves a channel.

channel.postMessage() will be covered in another article.

Thank you for reading and happy coding!

You may also enjoy,