Communication between tabs or windows

You may better use BroadcastChannel for this purpose. See other answers below. Yet if you still prefer to use localstorage for communication between tabs, do it this way:

In order to get notified when a tab sends a message to other tabs, you simply need to bind on ‘storage’ event. In all tabs, do this:

$(window).on('storage', message_receive);

The function message_receive will be called every time you set any value of localStorage in any other tab. The event listener contains also the data newly set to localStorage, so you don’t even need to parse localStorage object itself. This is very handy because you can reset the value just right after it was set, to effectively clean up any traces. Here are functions for messaging:

// use local storage for messaging. Set message in local storage and clear it right away
// This is a safe way how to communicate with other tabs while not leaving any traces
//
function message_broadcast(message)
{
    localStorage.setItem('message',JSON.stringify(message));
    localStorage.removeItem('message');
}


// receive message
//
function message_receive(ev)
{
    if (ev.originalEvent.key!='message') return; // ignore other keys
    var message=JSON.parse(ev.originalEvent.newValue);
    if (!message) return; // ignore empty msg or msg reset

    // here you act on messages.
    // you can send objects like { 'command': 'doit', 'data': 'abcd' }
    if (message.command == 'doit') alert(message.data);

    // etc.
}

So now once your tabs bind on the onstorage event, and you have these two functions implemented, you can simply broadcast a message to other tabs calling, for example:

message_broadcast({'command':'reset'})

Remember that sending the exact same message twice will be propagated only once, so if you need to repeat messages, add some unique identifier to them, like

message_broadcast({'command':'reset', 'uid': (new Date).getTime()+Math.random()})

Also remember that the current tab which broadcasts the message doesn’t actually receive it, only other tabs or windows on the same domain.

You may ask what happens if the user loads a different webpage or closes his tab just after the setItem() call before the removeItem(). Well, from my own testing the browser puts unloading on hold until the entire function message_broadcast() is finished. I tested to put some very long for() cycle in there and it still waited for the cycle to finish before closing. If the user kills the tab just in-between, then the browser won’t have enough time to save the message to disk, thus this approach seems to me like safe way how to send messages without any traces.

Leave a Comment