内容简介:Web 存储机制
Web存储机制,在这里主要聊有关于Web Storage API提供的存储机制,通过该机制,浏览器可以安全地存储键值对,比使用cookie更加直观。接下来简单的了解如何使用这方面的技术。
基本概念
Web Storage 包含两种机制:
-
sessionStorage
为每一个给定的源维持一个独立的存储区域,该区域在页面会话期间可用(即只要浏览器处于打开状态,包括页面重新加载和恢复) -
localStorage
同样的功能,但是在浏览器关闭,然后重新打开后数据仍然存在
这两种机制是通过 Window.sessionStorage
和 Window.localStorage
属性使用。更确切的说,在支持的浏览器中 Window
对象实现了 WindowLocalStorage
和 WindowSessionStorage
对象并挂在其 localStorage
和 sessionStorage
属性下。调用其中任一对象会创建 Storage
对象,通过 Storage
对象,可以设置、获取和移除数据项。对于每个源 sessionStorage
和 localStorage
使用不同的 Storage
对象。
例如,在文档中调用 localStorage
将会返回一个 Storage
对象,调用 sessionStorage
返回一个不同的 Storage
对象。可以使用相同的方式操作这些对象,但是操作是独立的。
在了解如何使用 localStorage
和 sessionStorage
之前,先来一下 Storage
对象。
Storage对象
Storage
对象作为Web Storage API的接口, Storage
提供了访问特定域名下的会话存储或本地存储的功能。例如,可以添加、修改或删除存储的数据项。
如果想操作一个域名的会话存储,可以使用 Window.sessionStorage
;如果想要操作一个域名的本地存储,可以使用 Window.localStorage
。
Storage对象的属性和方法
Storage
对象提供自己的属性和方法:
-
Storage.length
:返回一个整数,表示存储在Storage
对象中的数据项数量。这个是Storage
对象的一个属性,而且是一个 只读 属性。 -
Storage.key()
:该方法接受一个数值n
作为参数,并返回存储中的第n
个键名 -
Storage.getItem()
:该方法接受一个键名作为参数,返回键名对应的值 -
Storage.setItem()
:该方法接受一个键名和值作为参数,将会把键值对添加到存储中,如果键名存在,则更新其对应的值 -
Storage.removeItem()
:该方法接受一个键名作为参数,并把该键名从存储中删除 -
Storage.clear()
:调用该方法会清空存储中的所有键名
简单的示例
写一个简单的示例,页面就三个按钮: Set
、 Get
和 Remove
。按钮点击时,分别绑定三个函数: setStorage()
、 getStorage()
和 removeStorage()
:
-
setStorage()
:做了localStorage
和sessionStorage
存储,同时存的键名为name
,键值为W3cplus.com
-
getStorage()
:取得存储的name
,并打印出来 -
removeStorage()
:移除setStorage()
函数中存储的name
来看一下操作得到的效果。
首先点击 Set
按钮。使用浏览器开发者工具,我们可以看到 Local Storage
和 Session Storage
都存了一个 name
的键名,其对应的键值为 W3cplus.com
。如下图所示:
Local Storage截图
Session Storage截图
这个时候点击 Get
按钮,可以分别获取 setStorage()
存的 name
的值,并且输出:
接下来,再点击 Remove
按钮,再次打开开发者工具,查看 Local Storage
和 Session Storage
选项,可以看到,当初对应的 Key
和 Value
被清空了,比如下面截图是 Session Storage
:
这个时候,再次点击 Get
按钮,输出的内容为 null
:
上面我们看到的是第一种现象。我们再来看第二种。先点击 Set
按钮,再点击 Get
按钮,可以看到下面的输出的内容:
同样的页面,再不做 Remove
按钮操作,直接把浏览器窗口关闭,然后重新加载页面,并且直接点击 Get
按钮,看到的页面输出内容:
可以看出 localStorage
输出的内容还是 W3cplus.com
,而 sessionStorage
输出的内容变成 null
了。从这个效果也验证了前面提到的: sessionStorage
和 localStorage
类似,允许你访问一个 Storage
对象,只不过 sessionStorage
访问的是一个 session Storage
对象,而 localStorage
访问的是一个 local Storage
对象。另外不同之处在于 localStorage
里面存储的数据没有过期的时间设置,而存储在 sessionStorage
里面的数据在页面会话结束时会被清除。页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍然会保持原来的页面会话。在新标签或窗口打开一个页面会初始化一个新的会话( localStorage
的 key
的 value
依旧保存,而 sessionStorage
的 key
的 value
会被清除) 。
本地存储基本用法
前面的示例也演示过了,接下来拿 localStorage
来做示例:
localStorage.setItem('key', 'value'); // 设置一个localStorage,名称叫`key` localStorage.getItem('key'); // 获取存储的localStorage,获取的`key`对应的值`value` localStorage.removeItem('key'); // 移除存储的localStorage,删除的名称`key` localStorage.clear(); // 删除所有的localStorage
为了方便使用,可以对其进行封装。
设置localStorage
function setLocalStorage(key, value) { return localStorage.setItem(key, value); }
获取localStorage
function getLocalStorage(key) { return localStorage.getItem(key); }
移除localStorage
function removeLocalStorage(key) { return localStorage.removeItem(key); }
注: sessionStorage
使用方法和 localStorage
类似。
异常处理
localStorage
在目前的浏览器环境来说,还不是完全稳定的,可能会出现各种各样的问题,所以在设置 localStorage
时一定要考虑异常处理。 localStorage
的异常处理一般用 try/catch
来捕获/处理异常。所以我们在设置 localStorage
需要将 try/catch
添加进来,所以前面的 setLocalStorage()
函数可以修改成:
function setLocalStorage(key, value) { try { localStorage.setItem(key, value); } catch (e) { if (e.name === 'QUOTA_EXCEEDED_ERR' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') { console.log("Error: Local Storage limit exceeds."); localStorage.clear(); } else { console.log("Error: Saving to local storage."); } } }
如果考虑更具浏览器兼容性,我们还可以将上面的代码修改成:
function setLocalStorage(key, value) { try { localStorage.setItem(key, value); } catch(e) { if (isQuotaExceeded(e)) { console.log("Error: Local Storage limit exceeds."); localStorage.clear(); } else { console.log("Error: Saving to local storage."); } } } function isQuotaExceeded(e) { var quotaExceeded = false; if (e) { if (e.code) { switch (e.code) { case 22: quotaExceeded = true; break; case 1014: // Firefox if (e.name === 'NS_ERROR_DOM_QUOTA_REACHED') { quotaExceeded = true; } break; } } else if (e.number === -2147024882) { // IE8 quotaExceeded = true; } } return quotaExceeded; }
过期时间
就 localStorage
而言,其原生是不支持设置过期时间的,想要设置的话,就只能自己来封装一层逻辑来实现:
function setLocalStorage(key, value) { var curtime = new Date().getTime(); // 获取当前时间 // 转换成JSON字符串序列 var valueDate = JSON.stringify({ val: value, timer: curtime }); try { localStorage.setItem(key, valueDate); // 将JSON字符串设置为存储值 } catch(e) { if (isQuotaExceeded(e)) { console.log("Error: Local Storage limit exceeds."); localStorage.clear(); } else { console.log("Error: Saving to local storage."); } } } function isQuotaExceeded(e) { var quotaExceeded = false; if (e) { if (e.code) { switch (e.code) { case 22: quotaExceeded = true; break; case 1014: // Firefox if (e.name === 'NS_ERROR_DOM_QUOTA_REACHED') { quotaExceeded = true; } break; } } else if (e.number === -2147024882) { // IE8 quotaExceeded = true; } } return quotaExceeded; } function getLocalStorage(key,exp){ var vals = localStorage.getItem(key); // 获取本地存储的值 var dataObj = JSON.parse(vals); // 将字符串转换成JSON对象 // 如果(当前时间 - 存储的元素在创建时候设置的时间) > 过期时间 var isTimed = (new Date().getTime() - dataObj.timer) > exp; if (isTimed){ console.log("expires"); } else { var newValue = dataObj.val; } return newValue; }
这个时候我们调用:
setLocalStorage('name', 'hello, w3cplus.com!'); var localKey = getLocalStorage('name', 2); console.log(localKey);
如果我们把 exp
的时间修改一下:
setLocalStorage('name', 'hello, w3cplus.com!'); var localKey = getLocalStorage('name', 0); console.log(localKey);
作用域名
( 图片来自:https://segmentfault.com/a/1190000004121465 )
这里的所说的作用域名不是指函数中的作用域。而且 localStorage
存储的作用域。所以指的是如何隔离开不同页面之间的 localStorage
。 localStorage
只要在相同的协议、相同的主机名、相同的端口下,就能读取和修改到同一份 localStorage
存储的数据。而 sessionStorage
要比 localStorage
更苛刻一些,除了协议、主机名、端口外,还要求在同一窗口下。
容量限制
对于 localStorage
和 sessionStorage
存储是有一定的限制的,目前业界基本上统一为 5M
,要比 cookies
的 4K
大得多,一般情况已足够使用。如果存储的量大于最大值时,各浏览器都会抛出一个错误 QUOTA_EXCEEDED_ERR
。
浏览器兼容性
到目前为止 Web Storage得到众多主流浏览器的支持,有关于浏览器对其支持度,可以通过 Caniuse.com来查阅 。
总结
最近在做造物节项目,碰到了本地存储的需求,以前从示接触过,为了能较好的理解和整明白Web本地存储的相关知识,花了点时间学习了相关的知识,并做了一些笔记。因为初学相关知识,不免其中有错误之处,如果有不对之处,还请同行大婶拍砖指正。另外特别推荐一篇 @Mathias 整理的一篇文章《 How I detect and use localStorage 》。能帮助大家更好的理解有关于 localStorage
相关知识。如果你有更好的教程或经验,欢迎在下面的评论中与我们一起分享。
大漠
常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《 图解CSS3:核心技术与案例实战 》。
以上所述就是小编给大家介绍的《Web 存储机制》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- SpringSession:存储机制设计
- Kubernetes存储机制的实现
- Kafka 源码解析:日志数据存储机制
- 回顾 Android 11 中的存储机制更新
- kafka日志索引存储及Compact压实机制深入剖析-kafka 商业环境实战
- 块存储、文件存储、对象存储三者之比较
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Essential C++中文版
李普曼 (Stanley B.Lippman) / 侯捷 / 电子工业出版社 / 2013-8-1 / CNY 65.00
本书以四个面向来表现C++的本质:procedural(面向过程的)、generic(泛型的)、object-based(基于对象的)、objectoriented(面向对象的)。全书围绕一系列逐渐繁复的程序问题,以及用以解决这些问题的语言特性来组织。循此方式,你将不只学到C++的功能和结构,也可学到它们的设计目的和基本原理。 本书适合那些已经开始从事软件设计,又抽不出太多时间学习新技术的程......一起来看看 《Essential C++中文版》 这本书的介绍吧!