Using client-side storage, today.

I recently tried to store locally the content of a form to make it resilient to inadvertent tab closing and crashes. Here is what I learned about the different ways to achieve client-side storage.

Cookies can crumble

Cookies are not a valid storage mean, as their size is limited to roughly 4000 characters (4KB) and act as a ball and chain, slowing down the responsiveness of websites. localStorage on the other hand, has been designed for that exact purpose, but is not available in IE6, IE7 and Firefox3.

store.js to the rescue

The first task was thus to search for a fallback solution (or shim or polyfill) available in those older browsers. It turns out that store.js, by Marcus Westin (@marcuswestin), wraps localStorage and fallbacks together in a concise API, with a light file-size (2KB once minified and gzipped along with json2.js). Here is a short usage example:

How does it work?

On Firefox2 and Firefox 3, it uses the globalStorage API, and on IE6 and IE7 it falls back to userData behavior, which has two important limitations you should be aware of:

  • storage is limited to 128KB (vs. 5-10MB for localStorage), that’s still a lot of text,
  • storage is subject to a same folder policy, meaning that pages in different folders should not be able to access the same stored items.

The second limitation can be really annoying, but it is possible to work around it by loading the code in an iframe. This trick will likely be integrated into Marcus’ own code.

Although localStorage can only store strings, store.js uses the JSON API to make it possible to store Javascript objects and arrays as well.

Crash proof forms

With this script, I was able to build Persival, a simple jQuery plugin that can watch a form for changes and persist the values immediately:

A more complex demonstration page features the form people face when they want to report a bug affecting Firefox (you’ll see that it’s actually not as hard as it seems). If you start to fill the form, then close the tab and click on the same link again you should see the magic happening. A simple but welcome improvement to the user experience, isn’t it?

Chris Heilmann also demonstrated how client-side storage can be used to cache Web services data and maintain the state of a User Interface: localStorage and how to use it.

Your turn

Persival is young but already yours, feel free to use it, learn from it and improve it.

Maybe there is a similar topic you would like to see covered in a next blog post? Let us know!

About louisremi

Developer Relations Team, long time jQuery contributor and Open Web enthusiast. @louis_remi

More articles by louisremi…


20 comments

  1. Mathias

    You could make Persival even more “immediate” and responsive by using the oninput event if it’s available.

    April 5th, 2011 at 08:04

  2. louisremi

    @Mathias: good idea. Do you know in which browsers is this event not available?

    April 5th, 2011 at 08:19

  3. Mathias

    @louisremi: See http://blog.danielfriesen.name/2010/02/16/html5-browser-maze-oninput-support/

    April 5th, 2011 at 08:31

  4. Dextro

    I’ve been using jstorage for that task my self and it’s working mostly fine from what I could gather so far ( http://www.jstorage.info/ )

    April 5th, 2011 at 08:51

  5. Hemilton

    Mmmh, Iframes

    April 5th, 2011 at 13:58

  6. Mohamed Jama

    Hi,

    LocalStorage is quite cool We currently beta testing a project that uses LocalStorage to store user trips at expedia.co.uk on the third column search Expedia Map.

    At the moment its working on modern browsers only but hopefully we planning to fully implement it soon.

    April 5th, 2011 at 16:02

  7. Joss Crowcroft

    Awesome work dude – Persival is great. Doesn’t seem to retain state for checkboxes for me (Chrome on Mac) but everything else is awesome!

    April 5th, 2011 at 23:28

  8. louisremi

    @Joss: Indeed, I haven’t implemented “state persistence” for checkbox and radion-button yet. I’d love to see one of our reader giving it a try.

    April 6th, 2011 at 02:13

  9. Jaz

    If you want some seriously robust client-side storage options, check out http://persistencejs.org/ This is a true data object abstraction layer that works with various methods of client-side storage and, if you so desired, can synchronize with a server-side database through nodejs.

    April 6th, 2011 at 07:06

  10. louisremi

    @Jaz: the focus of this post was on cross-browser client-side storage. What persistance.js offers is more of a relational database API.

    Although it would be conceivable to cover this polyfill in a future post, it appears to scale only on browsers supporting the WebSQL API. As browser vendors are moving away from this API, I guess we should settle for key/value storage right now.

    April 6th, 2011 at 07:25

  11. Jaz

    @louisremi: currently persistence.js supports in-memory storage, google gears and websql, but the goal is to support whatever standard emerges, focusing on the need for robust local databasing. It would depend on your needs. For mobile development, iOS and Android currently use webkit, so websql is a great solution there. And persistence can use window.localStorage if it needs to, so it should be just as useful as anything else.

    April 6th, 2011 at 07:49

    1. louisremi

      @Jaz: persistence.js is indeed a valuable solution. I’d love to see an indexedDB adapter.

      April 7th, 2011 at 01:20

  12. iLama

    The only thing I have to say is that your implementation of this “solution” is horrible. I’m not sure exactly how the script does it, but it allows for “brute force” access (so to speak) of Opera’s local storage (it doesn’t even trigger the Opera to ask me if it’s okay). Until this bug is fixed, I’ll handle “store.js” as malicious code.

    April 6th, 2011 at 09:14

    1. louisremi

      @iLama: as localStorage is a very limited client-side storage (size limited to 5MB, no access to your file system), it doesn’t need to ask you for permission, unlike the file or geolocation APIs.
      This is not a bug, and if you think the implementation of store.js could be improved, feel free to fork it on Github.

      April 7th, 2011 at 01:16

  13. lobo_tuerto

    Have a look at the comments on Hacker News for this article, it must be worth something:

    http://news.ycombinator.com/item?id=2414662

    April 6th, 2011 at 09:28

  14. Jonatan Littke

    From a UX perspective, it’s a slippery slope using this on an edit form, where the value of the input field represents what’s currently stored in the database, and not what was lastly input.

    Imagine you edit something without saving, closing the page and coming back. if you then see your own text in one field you may get the impression the db has saved your edits, when in fact it hasn’t.

    April 7th, 2011 at 05:50

    1. louisremi

      Persival is probably not appropriate for every form out there, but it’s supposed to save the content of the form as the user type. What is restored should be you last entered.

      April 7th, 2011 at 06:00

  15. Ryan

    Is there any support for storing json objects as the namespace in IE? IE does not allow certain characters in “setAttribute” function.

    April 8th, 2011 at 10:25

    1. louisremi

      @Ryan: store.js stores every object as JSON.
      Have you got example of strings that are not accepted?

      April 8th, 2011 at 10:30

      1. Ryan

        Sure!

        Using the following value as the “key” will throw an error in IE6 and 7:

        {“Session”:”42.1″}

        April 8th, 2011 at 10:35

Comments are closed for this article.