Blog


DOM Storage Answers

In a follow-up to my previous post on DOM Storage, here's an attempt to answer some of the questions posed in the comments, and elsewhere.

What’s to stop a script from filling an entire storage area with random data?

As best as I can tell with the implementation in Firefox, every time you save data to a storage area, not only is the name of the storage area saved (e.g. "org" or "ejohn.org") but so is the domain name of the original script. This domain name is what has the 5MB limitation imposed upon it.

This means that a single script could put 2MB of data in globalStorage['org'] and another 3MB in globalStorage['ejohn.org'], but attempting to put any more data in will cause an error to occur.

I may be wrong on this point; but if that's the case, then it will be very hard to stop scripts from filling up "common" areas with nonsense data (and which seems like something that was considered as a fundamental design decision).

(Update: This is, currently, a moot point in Firefox as it does not enable any of the TLD or public storage areas, for fear of an issue like this happening.)

Storing data to globalStorage['localdomain']

I forgot to mention that all LAN addresses receive a TLD of 'localdomain'. For example, if your computer is named 'anthrax', you could store data in the following stores: globalStorage['anthrax.localdomain'], globalStorage['localdomain'], and globalStorage[''].

This means that you can, in fact, store data "globally" across all pages of an intranet.

What's with the name "DOM Storage"?

I've been having trouble pinpointing this one - but I agree, the name is particularly deceptive. What's especially confusing is that "DOM Storage" isn't the official name for this particular feature, "Client-side session and persistent storage" is.

As it happens, Mozilla's internal name of this features is "DOMStorage" (the names "Storage", "mozStorage", and "sessionStorage" were all already in use), I'm beginning to suspect that this naming confusion has stemmed from this, original, feature-naming. (Note: This has been confirmed.)

In reality, the storage area doesn't really have much to do with the Document Object Model - it really only attaches to the WindowHTML Object. The only time it actually interacts with the DOM, as we know it, is to trigger a "storage" event on the document body.

The storage event

I forgot to mention this in my last post, but this is a rather interesting sub-feature of DOM Storage. Whenever a key/value is changed, added, or removed within a storage area that you have permission to access, a 'storage' event is triggered, originating from the HTML document body and bubbling its way up.

The only piece of event metadata that is passed along in the event object is the name of the domain that the changed-key is within - and nothing else. (Providing any additional information would serve to be a security risk)

Update: Firefox does currently support this, and you can view a test case here.

Server-side Data

No data from DOM Storage areas is automatically passed to the server. This differs from cookies, which serve as a two-way form of synchronous communication between a server and a browser.

You could work around this limitation with an XMLHttpRequest, POSTing the contents of your relevant storage areas.

Known Bugs

As I mentioned before, Firefox has the only known implementation of DOM Storage available to any browser. However, there are still some serious limitations with it.

  • sessionStorage - Does not restore data across browser crash/restore.
  • globalStorage['org'] - Storing data to a single TLD fails
  • globalStorage[''] - Storing data to a public area fails

Update: Neil Deakin has gotten back to me and mentioned that the lack of TLD or public storage areas was intentional. When implementing the specification he felt that there was, quite simply, too much of a security risk in leaving those public areas open. I suspect that since Firefox is the first browser to make an attempt an implementation, much of this will trickle back to the specification.

We're still in the rocky first moments of this feature, but once it starts to pick up some solid adoption (especially amongst other browsers), I suspect that we'll see the level of quality really start to take off.

Tags: domstorage, whatwg, javascript, html5, firefox, mozilla

DOM Storage

The first thing that I tasked myself with, when I hopped on board with Mozilla, was to learn everything that I could about the new DOM Storage functionality provided in the HTML 5 specification. Interestingly, it's actually very impressive.

The brief summary: DOM Storage is a way to store meaningful amounts of client-side data in a persistent and secure manner.

I've written up a thorough piece of documentation on DOM Storage, and it can be found on the DevMo Wiki.

If you hadn't guessed already, DOM Storage is most similar, in nature, to HTTP Cookies. I'm going to already assume that you know how Cookies work, so with that in mind, here is how DOM Storage compares.

Storage Space

It is implied that, with DOM Storage, you have considerably more storage space than the typical user agent limitations imposed upon Cookies. However, the amount that is provided is not defined in the specification, nor is it meaningfully broadcast by the user agent.

If you look at the Mozilla source code we can see that 5120KB is the default storage size for an entire domain. This gives you considerably more space to work with than a typical 2KB cookie.

However, the size of this storage area can be customized by the user (so a 5MB storage area is not guaranteed, nor is it implied) and the user agent (Opera, for example, may only provide 3MB - but only time will tell.)

Storage / Retrieval

Where as in cookies you have to encode your key/value pairs into a string, along with other information (such as expiration and path), DOM Storage is a breath of fresh air. It provide a clean, JavaScript-like API for accessing and mutating key/value pairs. For example:

// Save a value
sessionStorage[ 'name' ] = "John";
// Display a value
alert( sessionStorage[ 'name' ] );
=> 'John'

This is absolutely fantastic, in comparison to Cookies. Note that, like with cookies, you can only store strings of data as a value. Additionally, no form of object serialization is provided by the browser, making some storage tasks non-trivial.

At this point, I'd be happy with one of two solutions: 1) For the user agent to take care of object (de)serialization for us, making it completely seamless or 2) To provide us with a really good, really fast, JSON (de)serializer. Honestly, I'd prefer the second solution, simply because it could be used in so many other situations. (And if I've heard right, one is definitely in the works by multiple browser vendors.)

Security

Cookies provide you with the ability to limit the accessibility of your key/value pairs to a certain domain, and even a certain path within that domain. DOM Storage works similarly, but only allows you to restrict access to domain (or TLD, or even public!) or session.

The data stored in a DOM Storage area is much more "public" than what's provided by cookies. For example, let's say you wanted to use DOM Storage on a public site like LiveJournal. There would be no way for you to hide your data from other users -- other than to choose a key that is completely private and un-reproducible; since there is no "path" limiter for DOM Storage.

Additionally, unlike in cookies, where you're immediately provided with all available key/value pairs for your particular domain (and path), in DOM Storage you must request a key by its specific name (you can't iterate through all available keys).

In short: If you are only using DOM Storage within a single domain (and you control that domain), then you have nothing to worry about - your data is very safe. In any other context you must choose a secure key name that cannot be duplicated by other clients on other sites (unless, of course, that's your goal).

Scope

DOM Storage provides you with a greater variety of scope for a piece of data, than for that of Cookies. For example, if I wanted to store a piece of data on this domain I could store it with the sessionStorage, globalStorage['ejohn.org'], globalStorage['org'], or globalStorage[''] DOM Storage areas. Here is how the restrictions break down:

  • sessionStorage is limited to the current browser session, only. No other client can access this data.
  • globalStorage['ejohn.org'] All pages on my web site have access to this area.
  • globalStorage['org'] All web sites with the TLD of 'org' can access this area (including, for example, mozilla.org).
  • globalStorage[''] All pages on all sites can access this area.

I, personally, think that we're going to see the most interesting results come from sessionStorage and globalStorage['']. sessionStorage for its practicality (which I'll discuss in a minute) and globalStorage[''] for its potential deviousness.

Duration

In DOM Storage it is not possible to specify an expiration period for any of your data. All expiration rules are left up to the user. In the case of Mozilla, most of those rules are inherited from the Cookie-related expiration rules. Because of this you can probably expect most of your DOM Storage data to last at least for a meaningful amount of time.

The one storage area that is particularly interesting (and where expiration does not apply) is that of sessionStorage. sessionStorage is seemingly useless at first blush - it only stores data within the context of a single session. However, there are two, very important, qualifiers to that:

  1. Data is persistent across page refreshes. This is nice because you can now help to protect against accidental page refreshes, by temporarily caching a user's unsaved data.
  2. Data is persistent across browser crashes. This is up to the user agent, but in the case of Firefox if you browser crashes, and you restore your previous session, then your sessionStorage area will be restored. (Well, that'll be the case once Firefox actually implements this feature).

This isn't to say that either of these features aren't possible using cookies, but the similar solution wouldn't be nearly as elegant.

Summary

In all, I'm really looking forward to digging in to DOM Storage - I think it has a lot of potential. Currently, the state of affairs is pretty slim (Firefox is the only browser that has an implementation, and even then, sessionStorage isn't terribly useful yet.) - but the future is bright.

As I mentioned before, if you're interested in some basic examples and documentation on the subject, feel free to read through the DOM Storage documentation that I wrote.

Update: Here's the original bug report that detailed its implementation in Gecko.

Tags: mozilla, domstorage, html5, whatwg, dom, javascript, firefox

JavaScript Books

Secrets of the JavaScript Ninja

JavaScript Secrets

Secret techniques of top JavaScript programmers.

Pro JavaScript Techniques

Pro JavaScript

The best techniques for professional JavaScript. Published by Apress.

Micro Updates

John Resig Twitter Updates

@jeresig

Infrequent, short, updates and links.

JavaScript Jobs



Hosting provided by: Ruby Hosting by Engine Yard