浏览器存储
在开发过程中,有些数据我们需要多次用到,但是如果每一次需要就去和服务器请求,那么无疑会造成一定的资源浪费,所以我们可以根据业务需求,把一些数据在浏览器中存储起来,目前最常见的存储方案是:
- Cookie
- web存储(localStorage和sessionStorage)
- IndexedDB
Cookie
背景
因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现。在典型的网上购物场景中,用户浏览了几个页面,买了一盒饼干和两瓶饮料。最后结帐时,由于HTTP的无状态性,不通过额外的手段,服务器并不知道用户到底买了什么,所以Cookie就是用来绕开HTTP的无状态性的“额外手段”之一。服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器会话中的状态。
Cookie的又称是HTTP Cookie,最初是在客户端用于存储会话信息,从底层来看,它作为HTTP协议的一种扩展实现,Cookie数据会自动在web浏览器和web服务器之间传输,因此在服务器端脚本就可以读写存储的cookie的值,因此Cookie通常用于存储一些通用的数据,比如用户的登陆状态,首选项等。虽然随着时代的进步,HTML5所提供的web存储机制已经逐步替代了Cookie,但有些较为老的浏览器还是不兼容web存储机制,因此正处于这个老旧更替阶段的我们对于它还是要了解了解的。
缺陷
- Cookie会被附加在每个HTTP请求中,所以无形中增加了流量。
- 由于在HTTP请求中的Cookie是明文传递的,所以安全性成问题,除非用超文本传输安全协定。
- Cookie的大小限制在4KB左右,对于复杂的存储需求来说是不够用的
- 只能储存字符串
- 由于第三方Cookie的滥用,所以很多老司机在浏览网页时会禁用Cookie,所以我们不得不测试用户是否支持Cookie,这也是很麻烦的一件事
优点
首先由于操作Cookie的API很早就已经定义和实现了,因此相比于其他的数据存储方式,Cookie的兼容性非常的好,兼容现在市面上所有的主流浏览器,我们在使用它的时候完全不用担心兼容问题。
web存储
web存储机制最初作为HTML5的一部分被定义成API的形式,但又由于其本身的独特性与其他的一些原因而剥离了出来,成为独立的一个标准。web存储标准的API包括locaStorage对象和seesionStorage对象。它所产生的主要原因主要出于以下两个原因:
- 人们希望有一种在cookie之外存储回话数据的途径。
- 人们希望有一种存储大量可以跨会话存在的数据的机制。
localStorage
localStorage对象在修订过的HTML5规范中作为持久保存客户端数据的方案取代了我们上面所提到的globalStorage。从功能上来讲,我们可以通过locaStorage在浏览器端存储键值对数据,它相比于cookie而言,提供了更为直观的API,且在安全上相对好一点 ,而且虽然localStorage只能存储字符串,但它也可以存储字符串化的JSON数据,因此相比于cookie,localStorage能存储更复杂的数据。总的来说相较于cookie,localStorage有以下优势:
- 提供了简单明了的API来进行操作
- 更加安全
- 可储存的数据量更大
也正是出于以上这些原因,localStorage被视为替代cookie的解决方案,但还是要注意不要在localStorage中存储敏感信息。
localStorage的基本操作很简单,示例如下:
1 | // 使用方法存储数据 |
但需要注意的是,我们上面的示例全是存储字符串格式的数据,当我们需要传输其他格式的数据时,我们就需要将这些数据全部转换为字符串格式,然后再进行存储:
1 | const user = {name:"Srtian", age: 22} |
当然,我们在获取值的时候也别忘了将其转化回来:
1 | var age = JSON.parse(localStorage.user) |
localStorage储存数据的有效期与作用域
通过localStorage存储的数据时永久性的,除非我们使用removeItem来删除或者用户通过设置浏览器配置来删除,负责数据会一直保留在用户的电脑上,永不过期。
localStorage的作用域限定在文档源级别的(意思就是同源的才能共享),同源的文档间会共享localStorage的数据,他们可以互相读取对方的数据,甚至有时会覆盖对方的数据。当然,localStorage的作用域同样也受浏览器的限制。
localStorage的兼容
localStorage的兼容如下表所示:
1 | Feature Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari (WebKit) |
sessionStorage
sessionStorage是web存储机制的另一大对象,sessionStorage 属性允许我们去访问一个 session Storage 对象。它与 localStorage 相似,不同之处在于 localStorage里面存储的数据没有过期时间设置,而Session Storage只存储当前会话页的数据,且只有当用户关闭当前会话页或浏览器时,数据才会被清除。
sessionStorage的基本语法
我们可以通过下面的语法,来保存,获取,删除数据,大体语法与:
1 | // 保存数据到sessionStorage |
下面的示例会自动保存一个文本输入框的内容,如果浏览器因偶然因素被刷新了,文本输入框里面的内容会被恢复,写入的内容不会丢失:
1 | // 获取文本输入框 |
在兼容性和优点方面,sessionStorage和localStorage是差不多的。
IndexedDB
虽然web存储机制对于存储较少量的数据非常便捷好用,但对于存储更大量的结构化数据来说,这种方法就不太满足开发者们的需求了。IndexedDB就是为了应对这个需求而产生的,它是由HTML5所提供的一种本地存储,用于在浏览器中储存较大数据结构的 Web API,并提供索引功能以实现高性能查找。它一般用于保存大量用户数据并要求数据之间有搜索需要的场景,当网络断开时,用户就可以做一些离线的操作。它较之SQL更为方便,不需要写一些特定的语法对数据进行操作,数据格式是JSON。
indexedDB的基本语法
indexedDB在浏览器存储数据相比于上面的方法更加复杂
首先,需要创建数据库,并指定数据库的版本号
1 | //版本号得是整数 |
然后我们需要生成处理函数,需要注意的是onupgradeneeded是我们唯一可以修改数据库结构的地方。在这里面,我们可以创建和删除对象存储空间以及构建和删除索引。
1 | request.onerror = function() { |
来个实例
1 | class IndexedDB{ |
IndexedDB的优点(相较于前面的存储方案)
- 拥有更大的储存空间
- 能够处理更为复杂和结构化的数据
- 拥有更多的交互控制
- 每个’database’中可以拥有多个’database’和’table’
IndexedDB的局限性
了解了IndexedDB的优点,我们当然也要来聊一聊IndexedDB的局限性与适用的场景:
1. 存储空间限制
一个单独的数据库项目的大小没有限制。然而可能会限制每个 IndexedDB 数据库的大小。这个限制(以及用户界面对它进行断言的方式)在各个浏览器上也可能有所不同:
- Firefox: 对 IndexedDB 数据库的大小没有限制。在用户界面上只会针对存储超过 50 MB 大小的 BLOB(二进制大对象)请求权限。这个大小的限额可以通过 dom.indexedDB.warningQuota 首选项进行自定义。(定义在 mxr.mozilla.org/mozilla-cen…)。
- Google Chrome:developers.google.com/chrome…ra…
2. 兼容性问题
从上面的图我们可以看出对于IndexedDB的兼容来讲比前面所提及的存储方案要差不少,因此在使用IndexedDB时,我们也要好好的考虑兼容性的问题
3. indexedDB受同源策略的限制
indexedDB使用同源原则,这意味着它把存储空间绑定到了创建它的站点的源(典型情况下,就是站点的域或是子域),所以它不能被任何其他源访问。要着重指出的一点是 IndexedDB 不适用于从另一个站点加载进框架的内容 (不管是 还是 。这是一项安全措施。详情请看这个:bugzilla.mozilla.org/show_bug.cg…
除此之外,IndexedDB还存在诸如:不适合存储敏感数据,相较于web存储机制的操作更加复杂等问题,这都是我们在使用IndexedDB时需要考虑的。