Ben Summers’ blog

Inter-window messaging using localStorage

Let’s say you have a web application which deals with “content”, so works much like a web site: one-page per item, and when you click a link, just load the next page. It’s very old fashioned, but it works the way the web works, and works well. Users are encouraged to have more than one page open at a time, and this works well, as it does for web sites.

Just like any other web application, you have some state on the server which is reflected on those pages, for example, which user is logged in, how many tasks they have to complete, how many items in their basket, and so on.

When you have multiple pages open, you can do something which changes that state, but it’s only reflected in the page which is returned in response. All the other windows show the old state. Wouldn’t it be nice to have a lightweight way of broadcasting state changes between the pages so they could update their state too?

Proper messaging systems

There are ways you can communicate between windows, for example, calling a user defined function on a window object, or using the new postMessage API (intended for cross-domain messaging). But for both of these, you need to have a reference to the other windows, so you can’t just broadcast to every window.

You can also use something like long polling or WebSockets to push events from the server, perhaps using Shared Web Workers to avoid opening one connection per page, but this feels like using a very large hammer to crack a very small nut.

Abusing localStorage for messaging

Interestingly, the widely supported Web Storage API provides a mechanism which could be abused to implement a lightweight messaging system, using window.localStorage and the “storage” event.

Whenever you change a bit of data in localStorage, the “storage” event is sent to every other window showing a page from the same hostname. Which is exactly what we want.

Here’s a proof-of-concept demo: localStorage inter-window messaging demo (opens in new window)

Open it multiple times, and then change the contents of the checkbox. It works beautifully in Firefox, Safari, Chrome, and even Internet Explorer.

So, the mechanism would look like:

  • When the page is initially loaded, write an item to window.localStorage with the current state.
  • Listen to events from other windows, and update the state when received.
  • Because the spec doesn’t guarantee swift delivery, and the user may navigate between pages, listen on the window object for the “focus” event and read the current state from localStorage and update.

Is this sensible?

I have a couple of questions:

  • Are there any problems with this scheme?
  • Am I missing a really obvious better way of doing this?

Feedback gratefully received. Thank you!


UPDATE The consensus seems to be that this is not entirely crazy, and there isn’t a better way. And Martin Kleppmann points out:


UPDATE 2 Some interesting discussion on Hacker News , including a comment that this is what localStorage was designed for, and Facebook and Google have been using it for years.

 

COMMENTS

blog comments powered by Disqus

 

Hello, I’m Ben.

I’m the Technical Director of ONEIS, a platform for information management.

 

About this blog

 

Twitter: @bensummers

 

Subscribe