Is there a way to listen to outgoing postMessages in Javascript?

2.3k views Asked by At

Is there any way to listen for postMessages at the origin page ?
Any event that gets fired when the current window object is sending a postMessage ?

I searched a lot but didn't really find anything.

Your help would be much appreciated. Thank you !

[Edit] The reason I'm trying to do this, is because I'm developing an extension to analyse the communication of pages. For example, how the page communicates with an inner IFrame or a new Window it opened. What i've done so far is injecting a Javascript-File into every IFrame/new Window, and adding a listener for messages to the window object. With this I can detect when a message has been received at the target. The problem is that I would like to get the full URL of the source, which isn't possible if it's cross-origin.

2

There are 2 answers

2
GibboK On

You can wrap window.postMessage() in a function and fire there a custom event (using a native custom event in JS, jQuery or another library of your preference).

Below an example using custom event (works on Chrome and Firefox). Please look in the console tab.

http://jsbin.com/liweyobazi/edit?html,output

<!doctype html>

<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Test</title>

    <script>

        window.app = {
            start: function () {
                // get the iframe
                var domain = '*';
                var iframe = document.getElementById('myIFrame').contentWindow;

                // listen to custom event
                document.body.addEventListener('postMessage', function (e) {
                    console.log('postMessage has been listened');
                }, false);


                function myPostMessage(message, domain) {
                    iframe.postMessage(message, domain); //send the message and target URI
                    // creat a custom event
                    var event = new Event('postMessage');
                    document.body.dispatchEvent(event);
                }

                // send preioducally messages for example
                setInterval(function () {
                    var message = 'Time is: ' + (new Date().getTime());
                    myPostMessage(message, domain); //send the message and target URI
                }, 1000);
            }
        };

    </script>

</head>

<body onload="window.app.start();">
    <iframe id="myIFrame" src="http://www.w3schools.com"></iframe>
</body>
</html>

Here a slight modified version, allow to pass to your custom function the original event for postMessage.

http://jsbin.com/liweyobazi/1/edit?html,console,output

Following your last EDIT in your question. This solution would work obviously only if you own "destination" source code and may not apply in your specific scenario (still I hope it is useful for also other readers).

0
Thomas Chille On

Monkey patching can do the trick:

const pm = window.postMessage;
window.postMessage = (msg, domain) => {
    console.log(msg);
    pm(msg, domain);
}