Question

I need to verify that Web Storage API is supported and available (it may be disabled due to security issues).

So, I thought it would suffice to check whether the type sessionStorage or localStorage is defined or not:

if (typeof sessionStorage != 'undefined')
{
    alert('sessionStorage available');
}
else
{
    alert('sessionStorage not available');
}

However, I was wondering if it could be possible that the type exists, but I wouldn't been able to use the Web Storage API anyway.

Remarks: I know Firefox will throw a security error if cookies are disabled and sessionStorage or localStorage are accessed.

Was it helpful?

Solution 4

So, because Modernizr.localstorage respectively Modernizr.sessionstorage will return true while Firefox might be used with disabled Cookies (which will lead into an security error) or any other proprietary (unexpected) behavior could occur: I've written my own webStorageEnabled function which seems to work very well.

function cookiesEnabled()
{
    // generate a cookie to probe cookie access
    document.cookie = '__cookieprobe=0;path=/';
    return document.cookie.indexOf('__cookieprobe') != -1;
}

function webStorageEnabled()
{
    if (typeof webStorageEnabled.value == 'undefined')
    {
        try
        {
            localStorage.setItem('__webstorageprobe', '');
            localStorage.removeItem('__webstorageprobe');
            webStorageEnabled.value = true;
        }
        catch (e) {
            webStorageEnabled.value = false;
        }
    }

    return webStorageEnabled.value;
}


// conditional

var storage = new function()
{
    if (webStorageEnabled())
    {
        return {
            local:   localStorage,
            session: sessionStorage
        };
    }
    else
    {
        return {
            local: cookiesEnabled() ? function()
            {
                // use cookies here
            }() : null,

            session: function()
            {
                var data = {};

                return {
                    clear: function () {
                        data = {};
                    },

                    getItem: function(key) {
                        return data[key] || null;
                    },

                    key: function(i)
                    {
                        var index = 0;
                        for (var value in data)
                        {
                            if (index == i)
                                return value;
                            ++index;
                        }
                    },

                    removeItem: function(key) {
                        delete data[key];
                    },

                    setItem: function(key, value) {
                        data[key] = value + '';
                    }
                };
            }()
        };
    }
}

Hope this will be useful for someone too.

OTHER TIPS

Why don't you use the Modernizr library to detect if local storage is supported or not? Any differences between browers will be taken care of for you, you can then just use code like this:

if (Modernizr.localstorage) {
    // browser supports local storage
} else {
    // browser doesn't support local storage
}

I think you're on the right track with your original code, no need to make this too fancy.

Using the KISS principle with no additional dependencies in your code:

var storageEnabled = function() {
    try {
        sessionStorage.setItem('test-key','test-value');
        if (sessionStorage.getItem('test-key') == 'test-value'){
            return true;
        }
    } catch (e) {};
    return false;
};

alert(storageEnabled() ? 'sessionStorage available' : 'sessionStorage not available');
try{
    ssSupport = Object.prototype.toString.call( sessionStorage ) === "[object Storage]";
}
catch(e){
    ssSupport = false;
}

My version (because IE 9 running in IE 8 more on an intranet site is broken).

if (typeof (Storage) != "undefined" && !!sessionStorage.getItem) {

}

a longer version that adds setObject to allow storing objects:

var sstorage;

if (typeof (Storage) != "undefined" && !!sessionStorage.getItem) {
    Storage.prototype.setObject = function (key, value) {
        this.setItem(key, JSON.stringify(value));
    };

    Storage.prototype.getObject = function (key) {
        return JSON.parse(this.getItem(key));
    };
    if (typeof sessionStorage.setObject == "function") {
        sstorage = sessionStorage;
    }
    else {
        setupOldBrowser();
    }
}
else {
    setupOldBrowser();
}


function setupOldBrowser() {
    sstorage = {};
    sstorage.setObject = function (key, value) {
        this[key] = JSON.stringify(value);
    };
    sstorage.getObject = function (key) {
        if (typeof this[key] == 'string') {
            return JSON.parse(this[key]);
        }
        else {
            return null;
        }
    };

    sstorage.removeItem = function (key) {
        delete this[key];
    };
}

Here's what I do to use session storage if available if it's not, use cookies..

var setCookie; 
var getCookie;

var sessionStorageSupported = 'sessionStorage' in window 
                                   && window['sessionStorage'] !== null;

if (sessionStorageSupported) {
    setCookie = function (cookieName, value) {
        window.sessionStorage.setItem(cookieName, value);
        return value; //you can introduce try-catch here if required
    };
    getCookie = function (cookieName) {
        return window.sessionStorage.getItem(cookieName);
    };
}
else {
    setCookie = function (cookieName, value) {
        $.cookie(cookieName, value);
        return value; // null if key not present
    };
    getCookie = function(cookieName) {
        console.log("using cookies");
        return $.cookie(cookieName);
    };
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top