Web Storage: sessionStorage与localStorage

下面将从零开始,分析 Web Storage 的前世今生:

前世

Web Storage API 提供了存储机制,通过该机制,浏览器可以安全地存储 键值对 ,比使用 cookie 更加直观。

Web Storage 的存储对象是简单的 键-值存储,类似于对象,但是它们在页面加载时保持完整。键和值始终是 字符串(请注意,与对象一样,整数键将自动转换为字符串)。

您可以像访问对象一样访问这些值,或者使用 Storage.getItem() 和 Storage.setItem() 方法 。

Storage 的存储使用方法如下:
Web Storage: sessionStorage与localStorage_初始化

Web Storage 包含如下两种机制:

  • sessionStorage 为每一个 给定的源(given
    origin)
    维持一个独立的存储区域,该存储区域在 页面会话 期间可用(即只要浏览器处于打开状态,包括页面重新加载和恢复)。
  • localStorage 同样的功能,但是在 浏览器关闭 ,然后 重新打开 后数据仍然存在

源码实现

\quad localStoragesessionStorage 机制是通过 Window.sessionStorageWindow.localStorage 属性使用。
\quad 更确切的说,在支持的浏览器中 Window 对象 实现了 WindowLocalStorageWindowSessionStorage 对象,并挂在其 localStoragesessionStorage 属性下)—— 调用其中任一对象会创建 Storage 对象,通过 Storage 对象,可以 设置(set)获取(get)移除(remove) 数据项。
\quad 对于每个 源(origin) 的 sessionStorage 和 localStorage 使用不同的 Storage 对象 —— 独立 运行和控制。

今生

sessionStorage

sessionStorage 属性允许你访问一个,对应当前源的 session Storage 对象。

它与 localStorage 相似,不同之处在于 localStorage 里面存储的数据没有 过期时间 设置,而存储在 sessionStorage 里面的数据在页面 会话(session)结束 时会被 清除(clear)

  1. 页面会话在浏览器 打开期间 一直保持,并且重新 加载恢复 页面 仍会保持 原来的页面会话。

  2. 新标签(new tab)窗口 打开一个页面时会复制顶级浏览会话的上下文作为新会话的上下文(context),这点和 session cookies 的运行方式不同。

  3. 打开多个 相同URLTabs 页面,会创建 各自sessionStorage

  4. 关闭对应浏览器 tab,会 清除 对应的 sessionStorage

下面通过 demo 验证 sessionStorage存储机制:

step1
demo1: Id为 "666"的用户登录后,观察该页面对应的session的值

Web Storage: sessionStorage与localStorage_初始化_02

2. step2
demo2: Id为 “555” 的用户登录后,观察浏览器中存在的 session 的值,demo1对应 session 依然存在,但 demo2 页面产生了全新的 session 会话。

Web Storage: sessionStorage与localStorage_加载_03

step3:
新tab页面: 打开完全相同的URL,但由于设置了导航守卫拦截非法请求;故,无法直接访问,返回首页。

Web Storage: sessionStorage与localStorage_数据_04

step4:

返回首页后,产生全新的session会话,demo1、demo2的session依然存在!

Web Storage: sessionStorage与localStorage_github_05

结论

sessionStorage 存储机制的主体,更多的是针对于浏览器的tab(单个页面)而言。
localStorage

localStorage 是针对 浏览器(Browser) 而言,local 的意思就是保存到本地,即使 浏览器关闭 ,重新打开后,localStorage的值依然存在!

如果要移除 localStorage 中的键 - 值对:

  1. 可以使用 localStorage.removeItem(key) .
  2. 可以通过 localStorage.clear().

3. StorageEvent

\quad 当前页面 使用的 storage 被其他页面修改时会触发 StorageEvent事件 (ps: 当前页面其他页面 要在 同一域名 下);在 同一页面 内发生的改变 不会触发 StorageEvent事件

Web Storage: sessionStorage与localStorage_数据_06

\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
);

属性

Web Storage: sessionStorage与localStorage_初始化_07

附录:

一、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对象