Search code examples
javascriptjquerylocal-storageofflinefallback

localStorage fallback attempt on file:// protocol


I am working on an offline website that based on js and html (of course), so it's being served via the file:// protocol.

In the website there's an option to mark items and add them to a list (like a "cart"). If it was an online version - I would use cookies and ajax/php. Since I can't use cookies (HTTP protocol), I found the localStorage object which fits to my requirements.

However, it seems that localStorage isn't really working on IE with file:// protocol, while on Chrome it does. (Like there aren't enough reasons to hate IE). And this is where my journey for localStorage alternative/fallback begin.

My fallback is to use the window.name to store data.

My code:

//Modernizr approach - is localStorage being supported?
function supportLocalStorage(){
    var test = 'test';
    try {
        localStorage.setItem(test, test);
        localStorage.removeItem(test);
        return true;
    } catch(e) {
        return false;
    }
}

$(document).ready(function(){
    if(supportLocalStorage() !== true){
        alert("boo"); 
        var localStorage = {
            getItem: function (key) {
                if(window.name == null || window.name == "")
                    return "{}"; //Later i'm about to use JSON Parser.
                return window.name;
            },
            setItem: function (key, val) {
                window.name = val;
            }
        }

    }

    var products_list = localStorage.getItem("products");
}

But now it seems that on IE everything is ok (no error), but on Chrome it gives the following error: (relates to the var products_list line)

Uncaught TypeError: Cannot read property 'getItem' of undefined

And if I remove the class declaration code-block of localStorage = {.. it works again on Chrome but not on IE. Why does it happen? Am I missing something?

Any suggestion/tip/help would be appreciated.


Solution

  • Your localStorage var declared inside if is hoisted to the top of the function and it shadowed the global localStorage variable.

    One solution to this may be setting local localStorage to global value at the top:

    $(document).ready(function(){
        var localStorage = window.localStorage;
        if(supportLocalStorage() !== true){
            alert("boo"); 
            localStorage = {
                getItem: function (key) {
                    if(window.name == null || window.name == "")
                        return "{}"; //Later i'm about to use JSON Parser.
                    return window.name;
                },
                setItem: function (key, val) {
                    window.name = val;
                }
            }
    
        }
    
        var products_list = localStorage.getItem("products");
    }