[javascript] Javascript communication between browser tabs/windows

What's the most reliable way to have Javascript communicate between tabs/windows of the same browser? For example, when Tab 2 starts audio playback, Tab 1 somehow knows about this and can pause it's player.

I'm building a site with a music player... so at the moment if you open two tabs to the site, you could start music on both. This is obviously bad, so I'm trying to find a solution.

Any ideas? Thanks

This question is related to javascript browser

The answer is


For a more modern solution check out https://stackoverflow.com/a/12514384/270274

Quote:

I'm sticking to the shared local data solution mentioned in the question using localStorage. It seems to be the best solution in terms of reliability, performance, and browser compatibility.

localStorage is implemented in all modern browsers.

The storage event fires when other tabs makes changes to localStorage. This is quite handy for communication purposes.

Reference:
http://dev.w3.org/html5/webstorage/
http://dev.w3.org/html5/webstorage/#the-storage-event


There is also an experimental technology called Broadcast Channel API that is designed specifically for communication between different browser contexts with same origin. You can post messages to and recieve messages from another browser context without having a reference to it:

var channel = new BroadcastChannel("foo");
channel.onmessage = function( e ) {
  // Process messages from other contexts.
};
// Send message to other listening contexts.
channel.postMessage({ value: 42, type: "bar"});

Obviously this is experiental technology and is not supported accross all browsers yet.


I don't think you need cookies. Each document's js code can access the other document elements. So you can use them directly to share data. Your first window w1 opens w2 and save the reference

var w2 = window.open(...) 

In w2 you can access w1 using the opener property of window.


You can do this via local storage API. Note that this works only between 2 tabs. you can't put both sender and receiver on the same page:

On sender page:

localStorage.setItem("someKey", "someValue");

On the receiver page

    $(document).ready(function () {

        window.addEventListener('storage', storageEventHandler, false);

        function storageEventHandler(evt) {
            alert("storage event called key: " + evt.key);
        }
    });

Found different way using HTML5 localstorage, I've create a library with events like API:

sysend.on('foo', function(message) {
    console.log(message);
});
var input = document.getElementsByTagName('input')[0];
document.getElementsByTagName('button')[0].onclick = function() {
    sysend.broadcast('foo', {message: input.value});
};

it will send messages to all other pages but not for current one.


Below window(w1) opens another window(w2). Any window can send/receive message to/from another window. So we should ideally verify that the message originated from the window(w2) we opened.

In w1

var w2 = window.open("abc.do");
window.addEventListener("message", function(event){
    console.log(event.data);
});

In w2(abc.do)

window.opener.postMessage("Hi! I'm w2", "*");

edit: With Flash you can communicate between any window, ANY browser (yes, from FF to IE at runtime ) ..ANY form of instance of flash (ShockWave/activeX)


You can communicate between windows (tabbed or not) if they have a child-parent relationship.

Create and update a child window:

<html>
<head>
<title>Cross window test script</title>
<script>
var i = 0;
function open_and_run() {
    var w2 = window.open("", "winCounter"); 
    var myVar=setInterval(function(){myTimer(w2)},1000);
}

function myTimer(w2) {
    i++;
    w2.document.body.innerHTML="<center><h1>" + i + "</h1><p></center>";
}
</script>
</head>
<body>
Click to open a new window 
<button onclick="open_and_run();">Test This!</button>    
</body>
</html>

Child windows can use the parent object to communicate with the parent that spawned it, so you could control the music player from either window.

See it in action here: https://jsbin.com/cokipotajo/edit?html,js,output


Communicating between different JavaScript execution context was supported even before HTML5 if the documents was of the same origin. If not or you have no reference to the other Window object, then you could use the new postMessage API introduced with HTML5. I elaborated a bit on both approaches in this stackoverflow answer.