html5 storage api

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

为什么要有 storage ?

我们已经有了 session 可以帮助我们存储信息,为何还需要 storage 呢?

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

storage 类型

storage 一共有两种

  1. localStorage

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

  2. sessionStorage

    这个存储对象的存储是暂时的,只保持在当前会话中,简单来说就是和浏览器的一个 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` 的键的个数

以上是 storageapi

唯一需要注意的是 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 特性,让我们方便快捷的存储数据,美中不足的是只能存储字符型数据,不过也很容易解决这个问题。同时利用监听事件,也可以实现不同窗口之间的广播机制。是非常实用的一个特性。

一篇文章图文并茂地带你轻松学会 HTML5 storage的更多相关文章

  1. 一篇文章图文并茂地带你轻松实践 HTML5 history api

    HTML5 history api 前言 由于笔者在网络上没有找到比较好的关于 history api 的实践案例,有的案例过于杂乱,没有重点,有些案例只是告诉读者 api 是什么,却没告诉怎么用,本 ...

  2. 一篇文章图文并茂地带你轻松学完 JavaScript 设计模式(一)

    JavaScript 设计模式(一) 本文需要读者至少拥有基础的 ES6 知识,包括 Proxy, Reflect 以及 Generator 函数等. 至于这次为什么分了两篇文章,有损传统以及标题的正 ...

  3. 一篇文章图文并茂地带你轻松学完 JavaScript 设计模式(二)

    JavaScript 设计模式(二) 本篇文章是 JavaScript 设计模式的第二篇文章,如果没有看过我上篇文章的读者,可以先看完 上篇文章 后再看这篇文章,当然两篇文章并没有过多的依赖性. 5. ...

  4. 一篇文章图文并茂地带你轻松学完 JavaScript 事件循环机制(event loop)

    JavaScript 事件循环机制 (event loop) 本篇文章已经默认你有了基础的 ES6 和 javascript语法 知识. 本篇文章比较细致,如果已经对同步异步,单线程等概念比较熟悉的读 ...

  5. 一篇文章图文并茂地带你轻松学完 JavaScript 继承

    JavaScript 继承 在阅读本文章之前,已经默认你了解了基础的 JavaScript 语法知识,基础的 ES6 语法知识 . 继承种类 简单的继承种类可以分为 构造函数继承 原型链继承 clas ...

  6. 一篇文章图文并茂地带你轻松学完 JavaScript 原型和原型链

    JavaScript 原型和原型链 在阅读本文章之前,已经默认你了解了基础的 JavaScript 语法知识,基础的 ES6 语法知识 . 本篇文章旨在为 JavaScript继承 打下基础 原型 在 ...

  7. 一篇文章图文并茂地带你轻松学完 JavaScript 闭包

    JavaScript 闭包 为了更好地理解 JavaScript 闭包,笔者将先从 JavaScript 执行上下文以及 JavaScript 作用域开始写起,如果读者对这方面已经了解了,可以直接跳过 ...

  8. 一篇文章让Oracle程序猿学会MySql【未完待续】

    一篇文章让Oracle DB学会MySql[未完待续] 随笔前言: 本篇文章是针对已经能够熟练使用Oracle数据库的DB所写的快速学会MySql,为什么敢这么说,是因为本人认为Oracle在功能性方 ...

  9. 一篇文章教你学会ASP.Net Core LINQ基本操作

    一篇文章教你学会ASP.Net Core LINQ基本操作 为什么要使用LINQ LINQ中提供了很多集合的扩展方法,配合lambda能简化数据处理. 例如我们想要找出一个IEnumerable< ...

随机推荐

  1. LSTM+CRF进行序列标注

    为什么使用LSTM+CRF进行序列标注 直接使用LSTM进行序列标注时只考虑了输入序列的信息,即单词信息,没有考虑输出信息,即标签信息,这样无法对标签信息进行建模,所以在LSTM的基础上引入一个标签转 ...

  2. 在HTML中改变input标签中的内容

    在HTML中改变input标签的内容 1.使用js自带的方法: document.getElementById('roadName').value='武汉路';//通过标签选择器来选择标签,然后设置值 ...

  3. Linux学习安装

    Linux学习安装 服务器指的是网络中能对其他机器提供某些服务的计算机系统,相对普通PC, 服务器指的是高性能计算机,稳定性.安全性要求更高 linux安装学习 1.虚拟机 一台硬件的机器 安装vmw ...

  4. 记录list.remove()和list.pop()

    list.remove(obj):这个是移除列表中某个值的第一个匹配项 list.pop(index):这个是移除列表中下标为index的元素 当元素全是数字或者有数字时注意区分.

  5. C++ unordered_map/unordered_set 自定义键类型

    1. unordered_map 和 unordered_set template < class Key, // unordered_map::key_type class T, // uno ...

  6. LOJ10145郁闷的出纳员

    传送门:https://loj.ac/problem/10145 简单的平衡树 ------------------------------------ 1 #include<bits/stdc ...

  7. SpringMVC听课笔记(十:处理JSON: 使用HttpMessageConverter)

    1. 处理JSON 2. 原理 流程图 3. 看个应用吧 -- 上传 ①jsp ②handler -- 下载 ① jsp ② handler

  8. 最短路-Bellmm-ford算法

    Bellmm-ford算法 解决什么样的问题 有边数限制的最短路,存在负权边,负环 概念 通俗的来讲就是:假设 1 号点到 n 号点是可达的,每一个点同时向指向的方向出发,更新相邻的点的最短距离,通过 ...

  9. java切割~~百万 十万 万 千 百 十 个 角 分

    /** * @param value * @return */ @SuppressWarnings("unused") public static void convertLoan ...

  10. thymeleaf第二篇:理解原理并为后面springboot进行整合进行铺垫

    官方入门之从虚拟商店理解thymeleaf 参考文档: 简单使用Thymeleaf API渲染模板生成静态页面 邮件通知改造之Thymeleaf渲染模板生成静态页面--看懂会帮助理解springboo ...