Sunday, September 22, 2013

Javascript : Web Storage - friend or foe?

Web Storage is super neat and fun to fly.

The advent of HTML5 (super hip, buzz word name drop) truly has brought about some neat stuff for us to use. One of these neat things is the concept of local storage in client browsers, or as it is also known - Web Storage. Web Storage, in spite of being a byproduct of HTML5, is a browser JavaScript feature.

In the early days of the web, there were all kinds of hacks that allowed the storing of user data and other small bits of data via the browser. The most widely used and adapted methods of which was probably the cookie. The cookie has limitations though, and is sent to and from the client to the server with every request made. This means that any hacks or workarounds still tend to result in an ultimately undesired scenario. More importantly, these methods (cookies and the like) are necessary because of the stateless nature of the web.



-um, idk - listen, can we talk outside the protest song? Here's the thing...

What is Web Storage?

Web Storage is a term that encompasses the idea of persisting data in client browsers via two new HTML5 browser objects; localStorage and sessionStorage. I have had developers speak to me of using web storage as a replacement or successor to MSSQL, Oracle and/or MySql. I really balk at this idea -centralized data is defacto for very sound reasons in my opinion. That said - there are some GREAT reasons for using web storage. Let's get into it and you can see and decide for yourself.

How does it work?

localStorage.myVar = "something";
sessionStorage.myVar = "something";
You set any variable onto localStorage or sessionStorage and it's persisted. If your browser supports Web Storage, the features are already built into your browser, available on the window object, and anything stored will remain there until it is expressly cleared via JavaScript. No fuss. No muss. (For the record, I neither know nor care what "muss" is).

Here is an example of Web Storage persistence:
You can run it, refresh it, clear your browser cache, and/or do whatever else you like, - the variables set on localStorage remain in tact. sessionStorage works the same way - excepting that anything stored via sessionStorage will collapse with the browsing session.

How can I delete stuff from web storage?

 delete localStorage.myVar; //or
 delete localStorage['myVar']; //or
 localStorage.removeItem('myVar'); //or
 localStorage.clear(); //will delete all vars
 //--or from sessionStorage--
 delete sessionStorage.myVar; //or
 delete sessionStorage['myVar']; //or
 sessionStorage.removeItem('myVar'); //or
 sessionStorage.clear(); //will delete all vars

Do I need to worry about other sites deleting my site's data in a client browser's Web Storage?

Well - no. It follows the same Same Origin Policy as everything else in JavaScript, so you should not have to worry about other sites coming in and deleting your data.

How is browser compatibility/support with regard to Web Storage?

Browser compatibility/support for web storage is pretty awesome; with one well placed line, you can check if your browser supports it or not. (You actually saw it in the fiddle above).

How can I check if a browser supports Web Storage?

if (typeof localStorage === "undefined") throw 'localStorage not supported';
if (typeof sessionStorage === "undefined") throw 'sessionStorage not supported';

Are there any gotchas/snafus/things I should be aware of before implementing?

As with anything else, there are a few caveats. Probably the most notable of which is the fact that localStorage and sessionStorage can only be used to store strings. They don't care about what you throw at them; they don't care what you try to put into them; they take what you give them, and store the JavaScript string primitive of that object or value.

Here is a fiddle:

Even though I set localStorage.mySuperObject equal to the instanced SuperObject ('o'), localStorage only stores strings, so it took my object and converted it to a JavaScript string primitive, then stored that. You may have encountered this behavior before. It's that ever-annoying and useless [object Object] string. More importantly, however, the data stored was useless. Also, stringifying any web storage variable for the sake of displaying it in html is kind of superfluous, but I did it anyway for posterity.

How can I use Web Storage to store meaningful information?

The solution should be somewhat clear at this point: JSON.stringify() and JSON.parse()

Here is the same fiddle from above - slightly modified:

In this fiddle, the object is stringified before it is set on localStorage. Then it is parsed back into JSON, making it as useful as it ever was. :D

What about namespacing in Web Storage, or perhaps some kind of data schema?

Here is what I came up with:

Web Storage can be dead-useful. It's definitely worth working with in situations where caching client side data or persisting client values is needed.

Are there major differences between localStorage and sessionStorage?

These two features work nearly identically. Anything pertinent to localStorage is also applicable to sessionStorage. The key difference is - sessionStorage does not persist beyond the current session.

Other key points:

  • Both localStorage and sessionStorage have built-in shortcut methods to some of the functionality you've already seen.
    Those methods are:
    • getItem(key) – returns the value for the given variable/member or null if the variable/member does not exist.
    • setItem(key, value) – sets the value for the given variable/member.
    • removeItem(key) – removes the variable/member from the storage object.
    • key(position) – returns the key for the variable/member in the given numeric position.
    • clear() - clears storage without prejudice
  • Saves (or setItem(key, value) calls) are best wrapped in try/catch because there are size constraints with Web Storage and the amount of data that can be stored in the localStorage and sessionStorage objects.
Any thoughts, tips, tricks, advice are all absolutely welcome!

No comments:

Post a Comment