一篇文章图文并茂地带你轻松学会 HTML5 storage

html5 storage api

localStoragesessionStoragehtml5 新增的用来存储数据的对象,他们让咱们能够以键值对的形式存储信息。html

为何要有 storage ?

咱们已经有了 session 能够帮助咱们存储信息,为什么还须要 storage 呢?前端

  1. 各个浏览器的 cookie 长度大概只能在 4kb 左右,而 storage 大概能达到 5M,这意味着能够存储更多的信息
  2. cookie 能够被后端更改,在每次进行网络请求的时候都会被发送给服务器,而 storage 不会,这意味着这个存储是彻底受控于前端(JavaScript)的。

storage 类型

storage 一共有两种html5

  1. localStoragechrome

    这个存储对象的存储和 origin 有关,即只要是同域名同协议同端口,存储是共享的。尽管关机了,或是关掉浏览器了,只要打开同源网站,存储的数据会依然存在,数据不会过时消失。后端

  2. sessionStorageapi

    这个存储对象的存储是暂时的,只保持在当前会话中,简单来讲就是和浏览器的一个 tab 有关,只要 tab 关掉了再打开数据就没了,可是在当前界面刷新的话,数据就还在(这个时候认为是一个 tab)。数组

两个 storageapi 很类似,下面以 localStorage 为例浏览器

localStorage 演示

基础 api

localStorage.setItem("name", "huro"); // 设置键值对

能够在 chrome 浏览器的控制台进行观察,这里已经设置上去了。下面也能够作相应的测试。服务器

localStorage.getItem("name"); // huro
localStorage.removeItem("name"); // 删除某个键
localStorage.clear(); // 删除全部键值对
localStorage.key(0); // 得到索引为 0 的key
localStorage.length; // 得到 `localStroage` 的键的个数

以上是 storageapicookie

惟一须要注意的是 key(index) 这个 apikey 被设置的前后是没有关系的。

类对象操做

也能够用类对象的方法操做

localStorage.name = "huro";
console.log(localStorage.name); // huro
delete localStorage.name; // 删除键

可是上面的作法不推荐,若是用的是某些特殊的 key 例如 length 就会报错,由于原先 localStorage.length 表示得到键值对长度,理应是不能修改的。

localStorage["length"] = 4; // 修改无效

所以不推荐用这个作法修改 storage

遍历键值

因为 storage 并无 Symbol.iterator 属性,这意味着 storage 不能用 for of循环遍历。如下有三种遍历方式。

假设咱们只有一个键值对 name: huro

  1. for in 循环
for (let key in localStorage) {
    console.log(key);
}

上述的写法是错误的,由于 for in 循环会遍历原型链上的属性和方法,所以须要稍做改善。

for (let key in localStorage) {
  if (!localStorage.hasOwnProperty(key)) {
    continue;
  }
  console.log(key);
}

这个时候就能正确的只打印出键 name

  1. 简单 for 循环
for(let i = 0; i < localStorage.length; i+= 1) {
  let key = localStorage.key(i);
  console.log(key);
}

这个时候能正确的只打印出键 name

  1. Object.keys()

这个方法会得到某个对象自身的 key,而不会管原型链上的

const keys = Object.keys(localStorage);
for(let key of keys) {
  alert(key);
}

并且得到的 key 是数组,具备 iterator 所以能够用 for of 遍历

这个时候能正确的只打印出键 name

只能是 string

storage 被设计出来比较不足的地方是,键和值都只能是 string 类型的,若是不是的话,会自动转换成 string

因为是隐式转换,初学者每每不知道,这意味着可能带来一些 bug

localStorage.user = { name: "huro" };
console.log(localStorage.user); // [object Object]

上述代码在存储 user 的时候,被自动调用 toString 方法,转化为了 [object Object]

storage 事件

storage 事件返回一个对象,里面包含几个参数

  1. key 改变的键
  2. oldValue => 旧值 || null
  3. newValue => 新值 || null
  4. url 触发这个事件的 url 地址
  5. storageArea 要么是 localStorage 要么是 sessionStorage 取决与是更改哪一个storage
// 1.html
window.addEventListener("storage", (state) => {
    console.log(state.key, state.value, state.url); // name huro ./2.html(实际 url 是绝对路径)
})

// 2.html
localStorage.setItem("name", "huro");

还记得咱们以前说过, localStorage 只要是同源均可以分享吗,这意味若是咱们打开了两个窗口,只要他们是同源的,咱们能够用上述的监听事件,监听另外一个端口修改 storage,也就是能够实现不一样的窗口之间的数据共享。

注意: 经测试,chrome edge 等现代浏览器不会触发自身文件或同文件的 storage 事件,即必须是两个不一样的 html 才会互相触发。

例如 test1.htmltest2.html 都设置了 storage 监听事件,且同源。

test1.htmlstorageapi 事件会触发 test2.html 的,可是不能触发自己的 storage 监听事件。

另外这里的 api 事件也有限制,通过笔者测试,彷佛只有

  1. setItem
  2. getItem
  3. removeItem

有效果,而 clear 事件是没有效果的。
上面全程用 localStorage 演示,

sessionStorage 也是相似的,读者有兴趣能够自行码一下代码。

总结

storage 是很好的一个 html5 特性,让咱们方便快捷的存储数据,美中不足的是只能存储字符型数据,不过也很容易解决这个问题。同时利用监听事件,也能够实现不一样窗口之间的广播机制。是很是实用的一个特性。

相关文章
相关标签/搜索