Skip to content

Instantly share code, notes, and snippets.

@remy
Created March 31, 2010 14:58
Show Gist options
  • Save remy/350433 to your computer and use it in GitHub Desktop.
Save remy/350433 to your computer and use it in GitHub Desktop.
Storage polyfill
if (typeof window.localStorage == 'undefined' || typeof window.sessionStorage == 'undefined') (function () {
var Storage = function (type) {
function createCookie(name, value, days) {
var date, expires;
if (days) {
date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
expires = "; expires="+date.toGMTString();
} else {
expires = "";
}
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
var nameEQ = name + "=",
ca = document.cookie.split(';'),
i, c;
for (i=0; i < ca.length; i++) {
c = ca[i];
while (c.charAt(0)==' ') {
c = c.substring(1,c.length);
}
if (c.indexOf(nameEQ) == 0) {
return c.substring(nameEQ.length,c.length);
}
}
return null;
}
function setData(data) {
data = JSON.stringify(data);
if (type == 'session') {
window.name = data;
} else {
createCookie('localStorage', data, 365);
}
}
function clearData() {
if (type == 'session') {
window.name = '';
} else {
createCookie('localStorage', '', 365);
}
}
function getData() {
var data = type == 'session' ? window.name : readCookie('localStorage');
return data ? JSON.parse(data) : {};
}
// initialise if there's already data
var data = getData();
return {
length: 0,
clear: function () {
data = {};
this.length = 0;
clearData();
},
getItem: function (key) {
return data[key] === undefined ? null : data[key];
},
key: function (i) {
// not perfect, but works
var ctr = 0;
for (var k in data) {
if (ctr == i) return k;
else ctr++;
}
return null;
},
removeItem: function (key) {
delete data[key];
this.length--;
setData(data);
},
setItem: function (key, value) {
data[key] = value+''; // forces the value to a string
this.length++;
setData(data);
}
};
};
if (typeof window.localStorage == 'undefined') window.localStorage = new Storage('local');
if (typeof window.sessionStorage == 'undefined') window.sessionStorage = new Storage('session');
})();
@hasdavidc
Copy link

I think the only workaround for private browsing Safari requires you to overwrite the localStorage/sessionStorage prototypes, as overriding the object itself has no effect.

window.localStorage.__proto__ = new Storage('local');

Here's the complete gist with more complete localStorage support detection: https://gist.github.com/hasdavidc/8527456

@folktrash
Copy link

Best Gist evar?

@maerean
Copy link

maerean commented May 30, 2014

How to detect if the polyfill is really needed (like on iOS in Private mode where the object exists but it throws exceptions (QuotaExceededError: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota) in all methods)

from https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js

function() {
    var mod = 'modernizr';
    try {
      localStorage.setItem(mod, mod);
      localStorage.removeItem(mod);
      return true;
    } catch(e) {
      return false;
    }
  }

@yehosef
Copy link

yehosef commented Jul 29, 2014

what about wrapping the function definition in the catch to handle support detection as in https://gist.github.com/yehosef/57df0ec37d5096222cf0

You can add more tests for firefox etc. if desired. I'm dealing specifically with the ios private mode browser.

@jarrodirwin
Copy link

I've combined the ideas from @hasdavidc and @yehosef to account for the non existence of webstorage in older browsers and to accommodate for Safari's private browsing.

I've also tweaked the sessionStorage code so that it acts independent of the localStorage and is unique per window per tab to mimic the native behaviour.

See https://gist.github.com/jarrodirwin/0ce4c0888336b533b2c4

@AdReVice
Copy link

AdReVice commented Jul 6, 2016

hello sir,,
i am quite new in web development..
i just wanted to make a website which can fetch users data and save it locally, using their cookies,..
so how can i do this..
language known by me- c,js,html5,css,jquery

@gamecss
Copy link

gamecss commented Jan 6, 2023

Great job!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment