Click here to Skip to main content
15,894,362 members
Articles / Web Development / HTML5

HTML5 Web Storage in Essence

Rate me:
Please Sign up or sign in to vote.
4.90/5 (55 votes)
15 Apr 2012CPOL11 min read 183K   1.3K   83  
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.
<!DOCTYPE html>
<html lang="en">
<head>
    <title>HTML5 Web Storage Demo</title>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=9;FF=3;OtherUA=4" />
    <script src="../JS/json2.js" type="text/javascript"></script>
</head>
<body>
<section>
    <h2>sessionStorage Demo</h2>

    <h3>sessionStorage Insurance Test</h3>
    <label id="lbCurrentCounter"></label>
    <input type="button" value="Counter++" onclick="sessionStorage.Counter++;" /><input type="button" value="Reset" onclick="sessionStorage.Counter = 0;" />
    <br />
    <em><a href="WebStorageDemo.htm" target="_blank">Open a new instance of this page</a> and click <strong>Counter++</strong> button above, you will see Counter value in different page instances keeps isolated.</em>
    <p><span id="spCurCounter"></span></p>
    <p>&nbsp;</p>
    <input type="button" value="Display Current sessionStorage" onclick="displaySessionStorage()" />
    <input type="button" value="Clear Session Storage" onclick="clearSessionStorage();" /><br /><div id="divSessionStorage"></div>
    <p>&nbsp;</p>
    <h2>Load localStorage</h2>
    <input type="button" value="Display Current localStorage" onclick="displayLocalStorage()" /><br /><span id="spLocalStorage"></span>
</section>

    <h2>StorageEvent Demo</h2>
    <fieldset style="width:400px;">
        <legend>Add an object into localStorage</legend>
        <label>Key: <input type="text" id="txtKey" /></label>
        <label>Value: <input type="text" id="txtVal" /></label>
        <input type="button" value="Add" onclick="localStorage.setItem($('txtKey').value, $('txtVal').value);" />
    </fieldset>
    <div id="informationBar"></div>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
<script type="text/javascript">
    function supportsLocalStorage() {
        return ('localStorage' in window) && window['localStorage'] !== null;
    }

//    if (typeof(document.onstoragecommit) != 'undefined') { // IE 9 RC
//        document.onstoragecommit = onStorageChanged;
//    }
//    else if (typeof (onstorage) != 'undefined') { // FF, Chrome, Safari
//        onstorage = onStorageChanged;
//    }
//    else {
//        alert('Your browser does NOT support onstorage event!');
    //    }

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

    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));
    }


    function displayLocalStorage() {
        var userProfile = localStorage.getObject('UserProfile');

        $('spLocalStorage').innerHTML = 'Nick Name: ' + userProfile.NickName + '<br />Email: ' + userProfile.EmailAddress;
    }
    function displaySessionStorage() {
        var userShoppingCart = sessionStorage.getObject('UserShoppingCart');

        if (!userShoppingCart) {
            $('divSessionStorage').innerHTML = '<br />UserShoppingCart does NOT exist in sessionStorage.';
            return;
        }

        var htmlStr = '<br /><table border="1"><caption>Items in Shopping Cart</cation><tr><td>Product ID</td><td>Product Name</td><td>Category ID</td><td>Price</td></tr>';

        for (var i = 0; i < userShoppingCart.length; i++) {
            htmlStr += '<tr><td>' + userShoppingCart[i].ProductID + '</td><td>' + userShoppingCart[i].ProductName + '</td><td>' + userShoppingCart[i].CategoryID + '</td><td>' + userShoppingCart[i].Price + '</td></tr>';
        }
        
        htmlStr += '</table>';
        $('divSessionStorage').innerHTML = htmlStr;
    }

    function clearSessionStorage() {
        //alert("Before clear the Counter's value in sessionStorage: " + sessionStorage.Counter);
        sessionStorage.clear(); 
        //alert(sessionStorage.Counter);  // Here will display 'undefined'
    }

    window.onload = function () {
        if (!supportsLocalStorage()) {
            alert('Sorry, your browser does not support Web Storage');
            return;
        }

        //        var evt = document.createEvent('StorageEvent');
        //        evt.initStorageEvent('storage', false, false, null, null, null,
        //        'http://localhost/StudyASPNet/HTML5/WebStorageDemo.htm', window.sessionStorage);
        //        evt.initStorageEvent('storage', false, false, 'key', 'oldValue', 'newValue',
        //        'http://localhost/StudyASPNet/HTML5/WebStorageDemo.htm', window.localStorage);

        //window.dispatchEvent(evt);

        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 subscribtion!');
            return;
        }

        // Initialize session counter
        if (!sessionStorage.Counter) {
            sessionStorage.Counter = 0; $('spCurCounter').innerHTML = 'Current Session Counter: <b>0</b>';
        }
        else {
            $('spCurCounter').innerHTML = 'Current Session Counter: <b>' + sessionStorage.Counter + '</b>';
        }

        // 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);

        // Fake user profile and store into local storage
        var userProfile = new UserProfile();
        userProfile.NickName = 'Wayne';
        userProfile.EmailAddress = 'WebMaster@WayneYe.com';
        localStorage.setObject('UserProfile', userProfile);
    }

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

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
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!

Comments and Discussions