I was searching for a way how to communicate between multiple tabs or windows in a browser (on the same domain, not CORS) without leaving traces. There were several solutions:
The first is probably the worst solution - you need to open a window from your current window and then you can communicate only as long as you keep the windows open. If you reload the page in any of the windows, you most likely lost the communication.
Second approach, using postMessage, probably enables cross-origin communication, but suffers the same problem as the first approach. You need to maintain a window object.
Third way, using cookies, store some data in the browser, which can effectively look like sending a message to all windows on the same domain, but the problem is that you can never know if all tabs read the "message" already or not before cleaning up. You have to implement some sort of timeout to read the cookie periodically. Furthermore you are limited by maximum cookie length, which is 4KB.
Fourth solution, using localStorage, seemed to overcome the limitations of cookies, and it can be even listen-to using events. How to use it is described in the accepted answer.
Edit 2018: the accepted answer still works, but there is a newer solution for modern browsers, to use BroadcastChannel. See the other answer for a simple example describing how to easily transmit message between tabs by using BroadcastChannel.
I created a module that works equal to the official Broadcastchannel but has fallbacks based on localstorage, indexeddb and unix-sockets. This makes sure it always works even with Webworkers or NodeJS. See pubkey:BroadcastChannel
Checkout AcrossTabs - Easy communication between cross-origin browser tabs. It uses a combination of postMessage and sessionStorage API to make communication much easier and reliable.
There are different approaches and each one has its own advantages and disadvantages. Lets discuss each:
LocalStorage
Pros:
Cons:
Cookies
Pros:
Cons:
The data is sent back to the server for every HTTP request (HTML, images, JavaScript, CSS, etc) - increasing the amount of traffic between client and server.
Typically, the following are allowed:
sessionStorage
Pros:
localStorage
.Cons:
localStorage
, tt works on same-origin policy. So, data stored will only be able available on the same origin.PostMessage
Pros:
Cons:
targetOrigin
and a sanity check for the data being passed on to the messages listener.A combination of PostMessage + SessionStorage
Using postMessage to communicate between multiple tabs and at the same time using sessionStorage in all the newly opened tabs/windows to persist data being passed. Data will be persisted as long as the tabs/windows remain opened. So, even if the opener tab/window gets closed, the opened tabs/windows will have the entire data even after getting refreshed.
I have written a JavaScript library for this, named AcrossTabs which uses postMessage API to communicate between cross-origin tabs/windows and sessionStorage to persist the opened tabs/windows identity as long as they live.
For those searching for a solution not based on jQuery, this is a plain JavaScript version of the solution provided by Thomas M:
There's a tiny open-source component to sync/communicate between tabs/windows of the same origin (disclaimer - I'm one of the contributors!) based around
localStorage
.https://github.com/jitbit/TabUtils
P.S. I took the liberty to recommend it here since most of the "lock/mutex/sync" components fail on websocket connections when events happen almost simultaneously
I wrote an article on this on my blog: http://www.ebenmonney.com/blog/how-to-implement-remember-me-functionality-using-token-based-authentication-and-localstorage-in-a-web-application .
Using a library I created
storageManager
you can achieve this as follows:There are other convenient methods as well to handle other scenarios as well
There is a modern API dedicated for this purpose - Broadcast Channel
It is as easy as:
Probably, apart from API cleanness, it is the main benefit of this API - no object stringification.
Currently supported only in Chrome and Firefox, but you can find a polyfill that uses localStorage.