--- title: LocalStorage slug: conflicting/Web/API/Window/localStorage tags: - 存储API - 离线 translation_of: Web/API/Window/localStorage translation_of_original: Web/API/Web_Storage_API/Local_storage original_slug: Web/API/Storage/LocalStorage ---
localStorage
与 sessionStorage
一样,都遵循同源策略,但是它是持续存在的。localStorage
首次出现于 Firefox 3.5。
// Save data to the current local store localStorage.setItem("username", "John"); // Access some stored data alert( "username = " + localStorage.getItem("username"));
本地存储(localStorage
)的持续存在对许多事情都有帮助,包括这个示例this tutorial on Codepen所演示的记录页面查看次数。
Storage
对象最近才加入标准,因此可能并不被所有浏览器支持。你可以通过在你的scripts代码前加入以下两段代码中某一段来规避在不能原生支持的执行环境使用localStorage
对象的问题。
该算法借助于cookies,对localStorage对象进行了严谨的实现。
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()
和localStorage.removeItem()
这两个函数进行添加、改变或删除一个键。使用方法为localStorage.yourKey = yourValue;和delete localStorage.yourKey;
进行设置和删除一个键并不是安全的做法。您也可以改变它的名字和使用它仅仅去管理文档的cookies而不管localStorage
这个对象。"; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"
改成"; path=/"
(并且改变对象的名字),可以使得这个 localStorage
的实现变为sessionStorage
的实现。然而,这种实现方式会使储存键值可以跨标签和窗口访问(而且只会在浏览器窗口被关闭时销毁),完全兼容的sessionStorage
实现会将储存键值访问权限限定在当前浏览上下文。下面是另一个,并不那么严谨的localStorage
对象的实现。相比上一个方法,它更简单且能与旧的浏览器良好兼容,如Internet Explorer < 8 (甚至能在 Internet Explorer 6 上正常工作)。它同样是使用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()
和localStorage.removeItem()
等方法获取、设置或删除一个键。使用方法localStorage.yourKey = yourValue;
获取、添加、改变或者删除一个键并不是安全的做法。您也可以改变它的名字和使用它仅仅去管理文档的cookies而不管localStorage
这个对象。"; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/"
改成"; path=/"
(并且改变对象的名字),可以使得这个 localStorage
的实现变为sessionStorage
的实现。然而,这种实现方式会使储存键值可以跨标签和窗口访问(而且只会在浏览器窗口被关闭时销毁),完全兼容的sessionStorage实现会将储存键值限定在当前浏览环境上下文。localStorage
和 globalStorage[location.hostname]
是一样的, 除了作用域是在 HTML5 origin (结构 + 主机名 + 非标准的端口), 并且 localStorage
是一个 Storage
实例 ,而globalStorage[location.hostname]
是一个 StorageObsolete
实例,下面将要讨论这个。 例如, http://example.com 无法访问与 https://example.com 相同的 localStorage
对象 ,但是它们可以访问同一个 globalStorage
. localStorage
是标准的接口,globalStorage
不是, 所以不要依赖于 globalStorage
。
请注意,给globalStorage[location.hostname]设置一个属性并不会影响到localStorage。拓展Storage.prototype
也不会影响globalStorage
对象,只有拓展StorageObsolete.prototype
才会影响。
Storage
的键和值都是以每个字符占2个字节的UTF-16字符串(DOMString)格式存储的。