Cross-Origin Communication with postMessage

With the use of postMessage() method, you can communicate between different windows or iframes. It is something you also make with simple AJAX request, but here there aren’t classical cross-origin restriction.

This is a JavaScript solution, so it works on the client side. If you want to send a cross-origin request, you need to set up your PHP headers on the receiver side to enable this type of cross communication. With postMessage(), you don’t need similar protocol, host or port to send a message to other domains code. Using this function, you can quickly get around the mixed origin problem safely because you can send the data to the correct location and then make all your processing on the same origin without any related error.

The use cases for this methodology is unique. I’ve used it for an advertisement solution where were the embedded iFrame banners had to communicate and send a message to the main window – where the ad script ran. With this trick, I were able to catch the iFrame load end and so on.

The postMessage() Method

This method has two main parameters:

  • message – a string or object which is our data,
  • targetOrigin – the URL where we send our message.

To send a message first, you need to get a window reference or an iframe instance where you will post your data. For this, you can use the window.open() return value or in case of an iFrame the contentWindow property.

targetWindow.postMessage('... string or object data ...', 'http://adamlaki.com');

Catch the Sent Data

On the receiver window the postMessage() trigger a message event where you can get the data like this:

window.addEventListener('message', function(e) { 
    var message = e.data; 
});

Security

If you don’t want to get any message from another site don’t add any listener for message event; if you expect data always validate the sender with a full URI on the event’s origin property.

If you are the sender of the message then always give a correct target origin instead of the * character.

Sending Data Through an iFrame

Let’s check out the previously mentioned example named communicating with an iFrame on a different domain.

Sender Site Code

In the sender code, you have to select the receiver iFrame, and you can post your data. For the target, we set the iFrame domain which is https://pineco.de.

window.onload = function() {
    // Get the iFrame and the button reference
    var receiver = document.getElementById('receiver').contentWindow,
    btn = document.getElementById('btn');

    function sendMessage(e) {
        // Send the message
        receiver.postMessage('Hi from pineco.de domain!', 'https://pineco.de');
    }

    // Register the event listener
    btn.addEventListener('click', sendMessage);
}

Receiver Site Code

On the receiver side, we just have to catch the detached event and process the given data.

window.onload = function() {
    // Get the message reference
    var messageElement = document.getElementById('message');

    function receiveMessage(e) {
        // Validate the origin
        if (e.origin !== "https://s.codepen.io")
            return;

        // Append the message data
        messageElement.innerHTML = "Az üzenet megérkezett: " + e.data;
     }

     // Register the event listener
     window.addEventListener('message', receiveMessage);
}

CodePen Example

In this example, you can see the above scripts in work. When you press the “Send message” button, you post your data to the iFrame which get it and update the code on the receiver side.

See the Pen Post Message Communication – Pine by Adam Laki (@adamlaki) on CodePen.

Summary

As you see the postMessage() can be powerful when you need a cross-origin communication. It is well supported so that you can use it your next project. It is a less popular method, but when you need it, it will do an excellent service.