Web Storage: sessionStorage与localStorage
下面将从零开始,分析 Web Storage 的前世今生:
前世
Web Storage API 提供了存储机制,通过该机制,浏览器可以安全地存储 键值对 ,比使用 cookie 更加直观。
Web Storage 的存储对象是简单的 键-值存储,类似于对象,但是它们在页面加载时保持完整。键和值始终是 字符串(请注意,与对象一样,整数键将自动转换为字符串)。
您可以像访问对象一样访问这些值,或者使用 Storage.getItem() 和 Storage.setItem() 方法 。
Storage 的存储使用方法如下:
Web Storage 包含如下两种机制:
sessionStorage
为每一个 给定的源(given
origin) 维持一个独立的存储区域,该存储区域在 页面会话 期间可用(即只要浏览器处于打开状态,包括页面重新加载和恢复)。localStorage
同样的功能,但是在 浏览器关闭 ,然后 重新打开 后数据仍然存在
。
源码实现
\quad localStorage 与 sessionStorage 机制是通过 Window.sessionStorage 和 Window.localStorage 属性使用。
\quad 更确切的说,在支持的浏览器中 Window 对象
实现了 WindowLocalStorage
和 WindowSessionStorage
对象,并挂在其 localStorage 和 sessionStorage 属性下)—— 调用其中任一对象会创建 Storage 对象,通过 Storage 对象,可以 设置(set)、获取(get) 和 移除(remove) 数据项。
\quad 对于每个 源(origin) 的 sessionStorage 和 localStorage 使用不同的 Storage 对象 —— 独立
运行和控制。
今生
sessionStoragesessionStorage
属性允许你访问一个,对应当前源的 session Storage
对象。
它与 localStorage
相似,不同之处在于 localStorage
里面存储的数据没有 过期时间 设置,而存储在 sessionStorage
里面的数据在页面 会话(session)结束 时会被 清除(clear)。
-
页面会话在浏览器 打开期间 一直保持,并且重新
加载
或恢复
页面 仍会保持 原来的页面会话。 -
在 新标签(new tab) 或 窗口 打开一个页面时会复制顶级浏览会话的上下文作为新会话的上下文(context),这点和 session cookies 的运行方式不同。
-
打开多个 相同URL 的 Tabs 页面,会创建 各自 的 sessionStorage。
-
关闭对应浏览器 tab,会
清除
对应的 sessionStorage。
下面通过 demo 验证 sessionStorage 的 存储机制:
step1
demo1: Id为 "666"的用户登录后,观察该页面对应的session的值
2. step2
demo2: Id为 “555” 的用户登录后,观察浏览器中存在的 session 的值,demo1对应 session 依然存在,但 demo2 页面产生了全新的 session 会话。
step3:
新tab页面: 打开完全相同的URL,但由于设置了导航守卫拦截非法请求;故,无法直接访问,返回首页。
step4:
返回首页后,产生全新的session会话,demo1、demo2的session依然存在!
结论
sessionStorage 存储机制的主体,更多的是针对于浏览器的tab(单个页面)而言。
localStoragelocalStorage 是针对 浏览器(Browser) 而言,local 的意思就是保存到本地,即使 浏览器关闭
,重新打开后,localStorage的值依然存在!
如果要移除 localStorage 中的键 - 值对:
- 可以使用
localStorage.removeItem(key)
. - 可以通过
localStorage.clear()
.
3. StorageEvent
\quad 当前页面 使用的 storage 被其他页面修改时会触发 StorageEvent事件
(ps: 当前页面、其他页面 要在 同一域名
下);在 同一页面
内发生的改变 不会触发 StorageEvent事件
;
\quad 无论何时,只要 Storage对象 发生变化时 (即 创建 / 更新 / 删除数据项
时),就会触发StorageEvent事件 (重复设置相同的 键值(key)
不会触发 StorageEvent事件
,Storage.clear() 方法至多触发一次该事件)。
不同域名
下的页面不能访问 相同
的 Storage对象。
例:
\quad 为 window对象 添加事件监听器(EventListener
):
window.addEventListener('storage', function(e) {
document.querySelector('.my-key').textContent = e.key;
document.querySelector('.my-old').textContent = e.oldValue;
document.querySelector('.my-new').textContent = e.newValue;
document.querySelector('.my-url').textContent = e.url;
document.querySelector('.my-storage').textContent = e.storageArea;
});
类似与 DOM树 的 初始化(Init),initStorageEvent()
为 StorageEvent 触发事件
的 初始化 方法,即,初始化新创建的Storage对象的属性.
方法描述
void initStorageEvent(
in DOMString typeArg,
in boolean canBubbleArg,
in boolean cancelableArg,
in DOMString keyArg,
in DOMString oldValueArg,
in DOMString newValueArg,
in DOMString urlArg,
in nsIDOMStorage storageAreaArg
);
属性
附录:
一、Storage 判空方法
方法1:
直接通过 运算符 “ ! ” 取反 判断:
if(!localStorage.getItem('bgcolor')) {
...
}
方法2:
通过 storage.length 的 长度值 判断:
if(storage.length == 0) {
...
}
二、Storage 对象的作用域
注:不同域名下的页面不能访问相同的 Storage对象
。
三、Storage.clear()
Storage.clear()
不接受参数,只是简单地 清空
域名对应的整个 存储对象。
四、Storage 重复设置相同 key,key对应的旧值(value) 会被覆盖。
ps:
各浏览器支持的 localStorage 和 sessionStorage 的容量上限
不同,故,请谨慎使用 Storage。
详情请参见: http://dev-test.nemikor.com/web-storage/support-test/
后续博客会逐步解析 Web 的 DOM树 以及 Event对象。