Click here to Skip to main content
Click here to Skip to main content
Articles » Web Development » HTML / CSS » HTML » Revisions
 
Go to top

HTML5 Web Storage in Essence

, 2 Mar 2011
Rate this:
Please Sign up or sign in to vote.
Web Storage is a brand new mechanism of storing HTTP state data, which was introduced in HTML5 to replace cookie. I delve deep into its client store mechanism and advantages compare to cookie, at the mean time I describe how JavaScript can manipulate it and also how browsers store localStorage.
This is an old version of the currently published article.

Background

Web Storage (also named DOM Storage) brought in two brand new objects: sessionStorage and localStorage. In Web Storage Spec, Ian Hickson documented that Web Storage is intended to solve two cases that are "not handled well by Cookies". They are:

  1. The first is designed for scenarios where the user is carrying out a single transaction, but could be carrying out multiple transactions in different windows at the same time.
  2. The second storage mechanism is designed for storage that spans multiple windows, and lasts beyond the current session. In particular, Web applications may wish to store megabytes of user data, such as entire user-authored documents or a user's mailbox, on the client side for performance reasons.

sessionStorage and localStorage are introduced by W3 in HTML5 to solve problems above, let's begin with a review of how Cookie currently works.

Current HTTP State Storage – Cookie

Mechanism

An HTTP Cookie was a set of key / value pairs which an HTTP web server requests a concrete client browser (i.e. User Agent - UA) to store on client's hard disk, when the UA request to the web server further, UA will wrap all the cookie data within the HTTP request header as long as following conditions are all satisfied:

  1. The cookie data has not expired.
  2. The requested domain is under exactly the same domain when cookie was stored.
  3. The requested path under the domain is the same one where cookie was stored.

Once the cookie expires, browser will delete it from local hard disk.

A common cookie example:

  1. An end user types www.foo.net in a browser's navigation bar and hits enter.
  2. www.foo.net returns HTTP status 200 message below (In the Green part, web server expected client browser to store two Cookie key/value pairs: WayneKey1=value1; WayneKey2=Value2, they could be accessible from the entire domain, and they will expire after 1 year):

    HTTP/1.1 200 OK 
    Content-type: text/html 
    <span style="COLOR: green">Set-Cookie: WayneKey1=value1;WayneKey2=Value2;domain=www.foo.net; 
    expires=Tue, 24-Feb-2012 07:13:22 GMT; path=/; HttpOnly</span> 
    
    
    (Response HTTP body)
  3. Browser received the HTTP response and stored the cookie key/values in plain text into user's hard disk.

  4. User did some interactions and requested back www.foo.net, browser will wrap the cookie data into request HTTP header.

    GET /Index.aspx HTTP 1.1 
    HOST: <a href="http://www.foo.net/">www.foo.net</a> 
    Accept: *.* 
    <span style="COLOR: green">Cookie: WayneKey1=value1;WayneKey2=Value2;</span> 
    
    (Request HTTP body)

Notes: In #4 above, if client browser does not support cookie or cookie is disabled by user, a fallback mechanism might be implemented by the HTTP Web server, which can usually store cookie data within the URL (for an instance example, ASP.NET can support storing cookie in URL by setting cookieless="UseUri" in web.config, refer: Cookieless ASP.NET), or alternatively, the Web server won't allow client to use its features.

Based on a server allocated Session ID storing in client cookie, Session object is widely used in all popular web servers to store temporary data on server side (could be memory, database or a dedicated session storage server and so on), in case client disabled cookie, web server might adopt the same strategy mentioned above (storing cookie in URL), or instead, they do not allow client to use its features except client gets cookie enabled.

Situation

Nowadays countless websites (for example Google, Facebook, Amazon, New York Times) rely on HTTP cookie to store data such as user preference, login information, shopping cart and so on. If you disable cookie in your browser and try to access many extremely popular web applications (like Facebook, Twitter, Gmail, Amazon and so on) today, you probably see screenshots below:

GoogleNoCookie.jpg

In one word, cookie enabled is a mandatory condition to use these web giants.

Cookie Drawbacks

I investigated and summarized a number of drawbacks of Cookie listed below (two W3C points mentioned at the beginning are included):

  • Size and count limit
    Most browsers limited cookie size to 4096 bytes and 300 maximum cookie count within a domain. IETF recommended limitation standard, refer: http://www.ietf.org/rfc/rfc2109.txt section 6.3.
  • Performance hit
    If a website uses cookie, then every HTTP request/response between server / browser must include all cookie key / values pairs in the HTTP header.
  • Security
    Cookie is stored in user's local hard disk in plaint text. If developers didn't deal with this appropriately, cookie/session hijacking could possibly happen.
  • Ability to store data separately for more than one instance of same web application
    Cookie is not easy to handle one use case: separate instances of the same web application to run in different windows without interfering with each other (sessionStorage is going to well-support that, I will describe it later in this post).

Web Storage Mechanism

Unlike cookie which passed between server/client and could be accessed by both of them, sessionStorage / localStorage are 100% stored in the client by a concrete browser, sessionStorage temporarily stores data in one HTTP session, localStorage stores permanent data into client hard disk. The advantage is obvious:

  • Data won't be passed through HTTP request/response, bandwidth will be saved.
  • There will be no 4KB limitation, web site has much more flexibility to store large data in client.
    Notes: W3C "recommended 5 megabytes localStorage size limitation per domain", and "welcome feedback", this is much larger than 4KB limitation in cookie.
  • Now that data won't be passed through network, this will be relatively more secure.
  • Considering further according to #3, a number of existing HTTPs connection in theory could use plain HTTP by adopting Web Storage, because there is no need to encrypt the data, the data is stored in client side. Since HTTPs usually have only 10% performance comparing with HTTP, eventually either performance will be improved or cost is saved (procuring cheaper server hardware).

In my humble opinion, Web Storage is one the greatest features in HTML5, and I believe it will lead an HTTP web state storage revolution in the near future! Why? Considering several stories listed below, I guess they will very possibly happen soon!

  1. Bandwidth save. You have an Email account of a popular Email service web application, and you use it daily, at very first time of your visit in a concrete browser. It stores your 300+ contacts list as well as your newest 20 email threads (first page) into your browser's local storage, and the data takes approximate 8 kilobytes in total. In future visits, this 8 kilobytes will not be transferred from the Email server.
  2. No download time = Better UX. You like watching videos from a popular video web site, which records video list (by default 10 latest watched videos) you've watched as well as indexed real video stream data. Every time you visit the web site, you have an ability to view your watching history and most important, you can re-watch any video in the list in a second – from your local storage.
  3. Surfing same web sites using more than one account simultaneously. For some reason, you registered two accounts in one web site, which uses session storage, and you can login with these two account in two browser tabs and interactive in isolation. For example, checking Gmail in two Tabs using two Gmail account at the same time.

Manipulating Storage in JavaScript

The Storage Interface

Both sessionStorage / localStorage are inherited from an interface Storage, it defined in Web Storage Spec:

interface Storage {
  readonly attribute unsigned long length;
  DOMString key(in unsigned long index);
  getter any getItem(in DOMString key);
  setter creator void setItem(in DOMString key, in any value);
  deleter void removeItem(in DOMString key);
  void clear();
};

Basic Operations

First things first, we need to check whether a concrete browser supports Web Storage or not, per Wikipedia: Comparison of layout engines (HTML5), IE8+ (IE8 does NOT support Storage Event, while IE9 RC supports), Firefox 3.5+, Safari 4.0+, Chrome 4.0+ all support Web Storage. We can write a simple JS function to check whether client browser supports Web Storage or not:

function supportsLocalStorage() {
    return ('localStorage' in window) && window['localStorage'] !== null;
}

if(supportsLocalStorage()) {
    // Web Storage invocation here
}
else {
    alert('Sorry, your browser does not support Web Storage');
}

If the browser does support, then invoking sessionStorage and localStorage in JavaScript is fairly easy. Sample code which demonstrates set / get / remove / clear items storage shows below:

// Set/Get locallStorage
localStorage.{key} = strValue;
var localVal = localStorage.{key};

// Set/Get sessionlStorage
sessionStorage.{key} = strValue;
var sessionVal = sessionStorage.{key};

// Remove an storage item
localStorage.removeItem('key')
sessionStorage.removeItem('key')

// Clear storage
localStorage.clear();
sessionStorage.clear();

Please be aware of one thing: both sessionStorage and localStorage can only store DOM string value, what if we want to store JavaScript object into them, the answer is definitely JSON string, and someone at StackOverFlow has provided an elegant way to extend Storage.setObject / getObject method by using JavaScript prototype, code shows below:

Storage.prototype.setObject = function (key, value) {
    this.setItem(key, JSON.stringify(value));
}
 
Storage.prototype.getObject = function (key) {
    return this.getItem(key) && JSON.parse(this.getItem(key));
}
 
// By extending Storage's prototype above, just simply add/get 
// JavaScript object into Storage
localStorage.setObject('key',objValue);
localStorage.getObject('key',objValue);
sessionStorage.setObject('key', objValue);
sessionStorage.getObject('key', objValue);

My attached WebStorageDemo shows how to store both DOM String and JSON String into sessionStorage / localStorage, code snippet and screenshot showing below:

Store several fake Shopping Cart items into sessionStorage:

function S4() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}
function Guid() {
    return (S4() + S4() + "-" + S4() + "-" + S4() + 
	"-" + S4() + "-" + S4() + S4() + S4());
}
function ShoppingCartItem() {
    this.ProductID = Guid();
    this.ProductName = '';
    this.CategoryID = -1;
    this.Price = -1.0;
}

// Fake items in shopping cart, and store into sessionStorage
var item1 = new ShoppingCartItem();
item1.ProductName = 'HP WebOS Topaz';
item1.CategoryID = 8;
item1.Price = 849.99;
var item2 = new ShoppingCartItem();
item2.ProductName = 'Apple Ipad II';
item2.CategoryID = 10;
item2.Price = 799.99;

var currentUserShoppingCart = new Array();
currentUserShoppingCart[0] = item1;
currentUserShoppingCart[1] = item2;
sessionStorage.setObject('UserShoppingCart', currentUserShoppingCart);

Delve Deep into sessionStorage / localStorage Mechanism

As I mentioned at the beginning, both sessionStorage /localStorage are "100% stored in the client by a concrete browser", the difference between them is that sessionStorage is window/tab isolated while localStorage is shared across pages under a domain, in other words, sessionStorage takes care of storing temporary data during an HTTP session life time happened in one browser window/tab, each window/tab can maintain its own session data; While localStorage stores data persists into user's hard disk, all pages under this concrete domain can manipulate the localStorage.

Let's again see a demo, I added a Counter which stored natural number into sessionStorage, and a clickable button can increase the Counter, code below:

<input type="button" value="Counter++"  önclick="sessionStorage.Counter++;" />

And I open two instances of the page, respectively click Counter++ on each page, then we will see each of them keeps its own counter:

On the contrary, data stored in localStorage could be accessed by all pages under the same domain, in the demo shown below, initially I inserted a fake UserProfile into localStorage, and then open another page which has different path but under the same domain, we will see UserProfile stored by first page can be retrieved.

Notes: Now that localStorage is shared, it therefore might be manipulated by more than one page simultaneously, W3 emphasized that the browser should implement Storage mutex to ensure the Thread safe of localStorage.

By achieving these mechanisms, sessionStorage / localStorage is supposed to replace Cookie with a more straight-forward, effective and secure manner.

Storage Event

W3 defines StorageEvent interface as below:

interface StorageEvent : Event {
  readonly attribute DOMString key;
  readonly attribute any oldValue;
  readonly attribute any newValue;
  readonly attribute DOMString url;
  readonly attribute Storage storageArea;
  void initStorageEvent(in DOMString typeArg, in boolean canBubbleArg, 
	in boolean cancelableArg, in DOMString keyArg, in any oldValueArg, 
	in any newValueArg, in DOMString urlArg, in Storage storageAreaArg);
};

Most famous browser (latest version) have implemented StorageEvent, see screenshot below below:

By reading their documents: IE 9, Firefox, Safari, the standard way to subscribe storage event is window.addEventListener('storage', onStorageChanged, false), unfortunately, after trying for 2 days, I recognized that it ONLY works in IE 9 RC at this timestamp (2/24/2011), even described by Safari official Dev document, it doesn't work! So I am demonstrating StorageEvent in IE 9 RC, in code below, I subscribe to storage event, once sessionStorage / localStorage items got changed, I check storage's key to determine further reaction:

if (window.addEventListener) { // IE9, FF, Chrome, Safari, Opera
    window.addEventListener('storage', onStorageChanged, false);
}
else if (window.attachEvent) {
    window.attachEvent("onstorage", onStorageChanged); // IE 8
}
else {
    alert('Sorry, your browser does not support DOM event subscription!');
    return;
}

function onStorageChanged(e) {
    if (e.key != '') { 
        switch (e.key) {
            case 'Counter': // Counter stored in sessionStorage
$('spCurCounter').innerHTML = 'Current Session Counter: ' + e.newValue + '';
                break;
            case 'UserShoppingCart':
                break;
            case 'UserProfile': // UserProfile stored in localStorage
break;
            default:
                $('informationBar').innerHTML += 'New localStorage object added, 
		Key: [<span style="color: red; ">' + e.key + '</span>] 
		Value: [<span style="color: red; ">' + e.newValue + '</span>].
';
                break;
        }
    }
}

The GIF below demonstrates that when I insert a new object into localStorage, onStorageChanged function was triggered on two page instances simultaneously, and displays the new inserted data at the same time:

Notes: Since data stored in localStorage can be accessed by all page instances under a domain, those page instances can monitor the change (StorageEvent) simultaneously, we can achieve "passing data crossing pages at the very same time" which was really hard to do beforehand.

Storage Location/Format

Let's finally look into how browser store localStorage: location and data format. Let's take IE9 and Google Chrome on Windows 7 as example, see table below:

Browser localStorage location Data Format
IE 9 RC %userprofile%\AppData\Local\Microsoft\Internet Explorer\DOMStore\ Plaint XML
Chrome %userprofile%\AppData\Local\Google\Chrome\User Data\Default\Local Storage SQLite

IE 9 actually stores localStorage items a simple XML file, below is how the XML stores UserProfile object in my demo:

<root>
    <item 
    name="UserProfile" 
    value="{&quot;NickName&quot;:&quot;Wayne&quot;,&quot;EmailAddress&quot;
    :&quot;WebMaster@WayneYe.com&quot;}"
    ltime="3439488560" 
    htime="30135140" />
</root>

Chrome stores data in a SQLite simple database table with two columns: Key and Value, screenshot below:

Demo Code Notes 

Please download WebStorageDemo.zip including all my sample code above, I've also put the compete demo on to my blog: http://WayneYe.com/Demo/HTML5/WebStorageDemo.htm.

Please note if you test my attached demo or try any code related with Web Storage in IE 9, please make sure you added X-UA-Capability meta information in your HTML header, or explicitly set both Browse mode/Document mode to Internet Explorer 9 Standards in IE Developer tool, otherwise you probably see JS errors since IE 6,7 does NOT recognize sessionStorage / localStorage.

<meta http-equiv="X-UA-Compatible" content="IE=9" />

Conclusion

Compared to HTTP Cookie, HTML5 Web Storage mechanism provides relatively more convenient, flexible, secure and faster way to store HTTP state data, it should replace HTTP Cookie gradually, especially nowadays most of the popular web browsers support it (although there might be several issues such as StorageEvent I mentioned above), they do conform to the W3C standard to store data in sessionStorage / localStorage. Ian Hickson "expected HTML 5 becomes Candidate Recommendation stage during 2012", let's be expecting and excited to see how things are going in the coming future.

Further Reading

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Wayne Ye
Software Developer (Senior) SAP Labs Shanghai
China China
Wayne is a software developer, Tech Lead and also a geek. He has more than 6 years' experience in Web development(server: ASP.NET (MVC), Web Service, IIS; Client: HTML/CSS/JavaScript/jQuery/AJAX), Windows development (Winform, Windows Service, WPF/Silverlight, Win32 API and WMI) and SQL Server. Deep understanding of GOF Design Patterns, S.O.L.i.D principle, MVC, MVVM, Domain Driven Design, SOA, REST and AOP.
 
Wayne's Geek Life http://WayneYe.com
 
Infinite passion on programming!
Follow on   Twitter

Comments and Discussions


Discussions posted for the Published version of this article. Posting a message here will take you to the publicly available article in order to continue your conversation in public.
 
GeneralMy vote of 5 PinmemberM Rayhan29-Nov-13 19:46 
GeneralMy vote of 5 PinmemberSonal.India9-May-13 7:24 
GeneralMy vote of 5 PinmemberGianni Gardini28-Feb-13 22:36 
GeneralMy vote of 5 PinmemberNicolas Gordillo2-Jan-13 5:01 
GeneralMy vote of 5 PinmemberPriyank Bolia23-Apr-12 19:33 
GeneralMy vote of 4 Pinmemberstooboo15-Apr-12 21:49 
GeneralMy vote of 5 Pinmembermanoj kumar choubey3-Feb-12 1:02 
GeneralMy vote of 5 PinmemberR2B215-Nov-11 8:55 
GeneralMy vote of 5 PinmemberKanasz Robert12-Nov-11 1:36 
GeneralMy vote of 5 PinmemberJovan Popovic28-Apr-11 9:36 
Generaluseful PinmemberCIDev22-Apr-11 10:20 
GeneralMy vote of 5 PinmemberMonjurul Habib2-Apr-11 10:43 
GeneralMy vote of 5 PinmemberCiumac Sergiu18-Mar-11 4:00 
GeneralMy vote of 5 PinmemberDr. Pfistershammer8-Mar-11 7:44 
GeneralRe: My vote of 5 PinmemberWayne Ye9-Mar-11 3:11 
GeneralMy vote of 5 PinmemberMember 30290408-Mar-11 4:06 
GeneralRe: My vote of 5 PinmemberWayne Ye9-Mar-11 3:11 
GeneralMy vote of 5 Pinmemberpclion8-Mar-11 2:10 
GeneralRe: My vote of 5 PinmemberWayne Ye9-Mar-11 3:10 
GeneralMy vote of 5 PinmemberL Hills7-Mar-11 23:33 
GeneralMy vote is 4 PinmemberSunasara Imdadhusen7-Mar-11 22:43 
GeneralMy vote of 3 PinmvpJohn Simmons / outlaw programmer4-Mar-11 1:47 
GeneralRe: My vote of 3 PinmemberWayne Ye4-Mar-11 4:00 
GeneralRe: My vote of 3 Pinmembersnoopy0017-Mar-11 23:09 
GeneralRe: My vote of 3 PinmemberWayne Ye8-Mar-11 2:37 
GeneralRe: My vote of 3 PinmvpJohn Simmons / outlaw programmer17-Mar-11 3:36 
GeneralRe: My vote of 3 PinmemberWayne Ye17-Mar-11 3:57 
GeneralMy vote of 5 PinmemberBryian Tan3-Mar-11 15:10 
Generalsuper cookies Pinmembered welch1-Mar-11 12:19 
GeneralRe: super cookies PinmemberWayne Ye1-Mar-11 14:48 
GeneralMy vote of 5 PinmvpMarcelo Ricardo de Oliveira1-Mar-11 6:58 
GeneralRe: My vote of 5 PinmemberWayne Ye1-Mar-11 14:39 
GeneralMy Vote of 5 PinmemberSridhar Subramanian1-Mar-11 6:17 
GeneralMy vote of 5 Pinmemberraja_krish1-Mar-11 1:21 
GeneralRe: My vote of 5 PinmemberWayne Ye1-Mar-11 2:20 
GeneralMy Vote of 5 PinmemberRaviRanjankr28-Feb-11 21:57 
GeneralRe: My Vote of 5 PinmemberWayne Ye28-Feb-11 22:23 
GeneralMy vote of 5 PinmembermaryNet28-Feb-11 21:49 
GeneralRe: My vote of 5 PinmemberWayne Ye28-Feb-11 22:23 
GeneralMy vote of 5 PinmemberStart Shining28-Feb-11 19:33 
GeneralMy vote of 5 PinmemberSean Yao28-Feb-11 15:05 
GeneralMy vote of 5 PinmemberMonjurul Habib28-Feb-11 9:36 
GeneralGood one PinmemberShahriar Iqbal Chowdhury28-Feb-11 3:02 
GeneralMy vote of 5 PinmemberShilanWang28-Feb-11 1:55 
GeneralMy vote of 5 Pinmembercanozurdo28-Feb-11 1:41 
GeneralRe: My vote of 5 PinmemberWayne Ye28-Feb-11 2:37 
GeneralNice article PinmemberAhmad Hyari28-Feb-11 0:09 
GeneralRe: Nice article PinmemberWayne Ye28-Feb-11 0:32 
GeneralMy vote of 5 Pinmemberdigital man27-Feb-11 22:00 
GeneralRe: My vote of 5 PinmemberWayne Ye28-Feb-11 0:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 3 Mar 2011
Article Copyright 2011 by Wayne Ye
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid