localStorage
is the same as sessionStorage
with the same same-origin rules applied but it is persistent. localStorage
was introduced in Firefox 3.5.
// Save data to the current local store localStorage.setItem("username", "John"); // Access some stored data alert( "username = " + localStorage.getItem("username"));
localStorage
's persistence makes it useful for a variety of things, including page view counters as demonstrated in this tutorial on Codepen.
Compatibility
Storage
objects are a recent addition to the standard. As such they may not be present in all browsers. You can work around this by inserting one of the following two codes at the beginning of your scripts, allowing use of localStorage
object in implementations which do not natively support it.
This algorithm is an exact imitation of the localStorage
object, but makes use of cookies.
if (!window.localStorage) { Object.defineProperty(window, "localStorage", new (function () { var aKeys = [], oStorage = {}; Object.defineProperty(oStorage, "getItem", { value: function (sKey) { return sKey ? this[sKey] : null; }, writable: false, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "key", { value: function (nKeyId) { return aKeys[nKeyId]; }, writable: false, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "setItem", { value: function (sKey, sValue) { if(!sKey) { return; } document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"; }, writable: false, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "length", { get: function () { return aKeys.length; }, configurable: false, enumerable: false }); Object.defineProperty(oStorage, "removeItem", { value: function (sKey) { if(!sKey) { return; } document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; }, writable: false, configurable: false, enumerable: false }); this.get = function () { var iThisIndx; for (var sKey in oStorage) { iThisIndx = aKeys.indexOf(sKey); if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); } else { aKeys.splice(iThisIndx, 1); } delete oStorage[sKey]; } for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); } for (var aCouple, iKey, nIdx = 0, aCouples = document.cookie.split(/\s*;\s*/); nIdx < aCouples.length; nIdx++) { aCouple = aCouples[nIdx].split(/\s*=\s*/); if (aCouple.length > 1) { oStorage[iKey = unescape(aCouple[0])] = unescape(aCouple[1]); aKeys.push(iKey); } } return oStorage; }; this.configurable = false; this.enumerable = true; })()); }
localStorage.setItem()
and localStorage.removeItem()
to add, change, or remove a key. The use of methods localStorage.yourKey = yourValue;
and delete localStorage.yourKey;
to set or delete a key is not a secure way with this code. You can also change its name and use it only to manage a document's cookies regardless of the localStorage object."; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"
to: "; path=/"
(and changing the object's name), this will become a sessionStorage
polyfill rather than a localStorage
polyfill. However, this implementation will share stored values across browser tabs and windows (and will only be cleared when all browser windows have been closed), while a fully-compliant sessionStorage implementation restricts stored values to the current browsing context only.Here is another, less exact, imitation of the localStorage
object. It is simpler than the previous one, but it is compatible with old browsers, like Internet Explorer < 8 (tested and working even in Internet Explorer 6). It also makes use of cookies.
if (!window.localStorage) { window.localStorage = { getItem: function (sKey) { if (!sKey || !this.hasOwnProperty(sKey)) { return null; } return unescape(document.cookie.replace(new RegExp("(?:^|.*;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*"), "$1")); }, key: function (nKeyId) { return unescape(document.cookie.replace(/\s*\=(?:.(?!;))*$/, "").split(/\s*\=(?:[^;](?!;))*[^;]?;\s*/)[nKeyId]); }, setItem: function (sKey, sValue) { if(!sKey) { return; } document.cookie = escape(sKey) + "=" + escape(sValue) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"; this.length = document.cookie.match(/\=/g).length; }, length: 0, removeItem: function (sKey) { if (!sKey || !this.hasOwnProperty(sKey)) { return; } document.cookie = escape(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; this.length--; }, hasOwnProperty: function (sKey) { return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie); } }; window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length; }
localStorage.getItem()
, localStorage.setItem()
, and localStorage.removeItem()
to get, add, change, or remove a key. The use of method localStorage.yourKey
in order to get, set, or delete a key is not permitted with this code. You can also change its name and use it only to manage a document's cookies regardless of the localStorage object."; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"
to: "; path=/"
(and changing the object's name), this will become a sessionStorage
polyfill rather than a localStorage
polyfill. However, this implementation will share stored values across browser tabs and windows (and will only be cleared when all browser windows have been closed), while a fully-compliant sessionStorage implementation restricts stored values to the current browsing context only.Compatibility and relation with globalStorage
localStorage
is also the same as globalStorage[location.hostname]
, with the exception of being scoped to an HTML5 origin (scheme + hostname + non-standard port) and localStorage
being an instance of Storage
as opposed to globalStorage[location.hostname]
being an instance of StorageObsolete
which is covered below. For example, http://example.com is not able to access the same localStorage
object as https://example.com but they can access the same globalStorage
item. localStorage
is a standard interface while globalStorage
is non-standard so you shouldn't rely on these.
Please note that setting a property on globalStorage[location.hostname]
does not set it on localStorage
and extending Storage.prototype
does not affect globalStorage
items; only extending StorageObsolete.prototype
does.
Storage format
Storage
keys and values are both stored in the UTF-16 DOMString format, which uses 2 bytes per character.