Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a standard way for recognizing your own postMessage in the onmessage eventhandler?

I have an iframe-based widget that uses postMessage to communicate to the parent. That means i.e. that I send a message from the iframe to request a resize of itself. The data is json, and is at the moment interfering with messages sent by other widgets / scripts on the parent page.

So I need a way to distinguish my own messages from the others.

Now I'm thinking about simply adding an { app: 'Poules.com', [...] } parameter and check for that parameter before processing the message.

But before I do: are there already any established contracts for this?

Sending code:

parent.postMessage( JSON.stringify(data), page.widgetOrigin );

Receiving end:

poules.sdk.receiveMessage = function(event)
{
    var data = JSON.parse( event.data );

    switch ( data.message )
    {
        case 'requestResize':   poules.sdk.requestResize( data ); break;
        case 'loginSuccess':    poules.sdk.triggerLoginEvent( data ); break;
        default: throw "poules.sdk: can't parse message: " + event.data;
    };
}
like image 286
Dirk Boer Avatar asked Sep 30 '22 05:09

Dirk Boer


1 Answers

When you receive the message event, you must check event.origin to make sure it's coming from an origin you want to receive messages from. This is usually sufficient to differentiate them from other messages.

So:

poules.sdk.receiveMessage = function(event)
{
    if (event.origin != "http://poules.com") { // or whatever
        return;
    }

    var data = JSON.parse( event.data );

    switch ( data.message )
    {
        case 'requestResize':   poules.sdk.requestResize( data ); break;
        case 'loginSuccess':    poules.sdk.triggerLoginEvent( data ); break;
        default: throw "poules.sdk: can't parse message: " + event.data;
    };
}

This is for two reasons:

  1. It filters out messages from windows unrelated to what you're doing, and

  2. It filters out malicious messages trying to impersonate your widget and trick the main page into doing things it shouldn't do

More about event.origin on MDN; here's a note about how the string is formed:

origin

The origin of the window that sent the message at the time postMessage was called. This string is the concatenation of the protocol and "://", the host name if one exists, and ":" followed by a port number if a port is present and differs from the default port for the given protocol. Examples of typical origins are https://example.org (implying port 443), http://example.net (implying port 80), and http://example.com:8080. Note that this origin is not guaranteed to be the current or future origin of that window, which might have been navigated to a different location since postMessage was called.

like image 154
T.J. Crowder Avatar answered Oct 01 '22 19:10

T.J. Crowder