Cookie
因为HTTP是无状态的,每次的请求都是独立的,不会受上一次请求状态的影响,也不会影响下一次的请求进程,导致服务器并不知道这个用户是谁,因此,浏览器端通过Cookie来存储用户的信息,并在每一次请求时携带。
同时,Cookie存在以下问题
- Cookie不够大
Cookie的单个value的大小限制约为4KB,对于复杂的存储需求来说是不够用的。此外,浏览器对一个站点的Cookie个数也有限制,如chrome为150条。
这里需注意:各浏览器的cookie每一个name=value的value值大概在4k,所以4k的大小并不是一个域名下所有的cookie共享的,而是一个name的大小。
- Cookie 会增加不必要的请求头大小
由于同域的请求都会自动携带Cookie,无用的Cookie每次传输都会携带,造成流量的浪费
一般来说,Cookie都是通过服务器返回的响应头中的set-cookie设置的,浏览器端通过js手动设置cookie并不是一个很规范的操作,因为Cookie 的本职工作并非本地存储,而是“维持状态”。
如果想在浏览器本地缓存一些信息,推荐使用Web Storage。
Web Storage
Web Storage分为localStorage和sessionStorage
localStorage:
- 除非删除,数据永久存在
- 可以跨标签页遵循同源策略传递
- 大小约5M
- 存储在浏览器,不和服务端进行通信
- 接口封装好,使用便捷
- 同步执行
- 只能存储字符串
sessionStorage:
- 会话级别的浏览器存储,标签页关闭即清空,不可跨标签页传递
- 大小约5M
- 存储在浏览器,不和服务端进行通信
- 接口封装好,使用便捷
- 同步执行
- 只能存储字符串
Web Storage目前仍是浏览器缓存的主流方案,如果想要做浏览器本地缓存,优先考虑的还是Web Storage,但是很显然,Web Storage的方式有几个缺点:
- 只能存储字符串,有些对象无法转为JSON(如FileHandle对象)
- 只能存5M,如果数据量大很容易炸掉页面
- 没有索引(面对巨量数据需要索引提高搜索速度的性能,当然,Web Storage也无法存储巨量数据)
indexedDB
indexedDB正是解决了这几个问题。
indexedDB是一种低级API,用于客户端存储大量结构化数据(包括文件和blobs),是一个运行在浏览器上的非关系型数据库,使用索引来实现对该数据的高性能搜索。
indexedDB 具有以下特点:
- 键值对储存。 indexedDB 内部采用对象仓库(object store)存放数据。所有类型的数据都可以直接存入,包括 JavaScript 对象。对象仓库中,数据以"键值对"的形式保存,每一个数据记录都有对应的主键,主键是独一无二的,不能有重复,否则会抛出一个错误。
- 异步。 indexedDB 操作时不会锁死浏览器,用户依然可以进行其他操作,这与 LocalStorage 形成对比,后者的操作是同步的。异步设计是为了防止大量数据的读写,拖慢网页的表现。
- 支持事务。 IndexedDB 支持事务(transaction),这意味着一系列操作步骤之中,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。
- 同源策略。IndexedDB 受到同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库。
- 储存空间大。IndexedDB 的储存空间比 LocalStorage 大得多,一般来说不少于 250MB,甚至没有上限。
- 支持二进制储存。 IndexedDB 不仅可以储存字符串,还可以储存对象,二进制数据等(ArrayBuffer 对象和 Blob 对象)。
上面也说到,indexedDB是一种低级的API,如果想用原生写代码需要较为繁琐的操作。
IndexedDB鼓励使用的基本模式如下所示:
- 打开数据库。
- 在数据库中创建一个对象仓库(object store)。
- 启动一个事务,并发送一个请求来执行一些数据库操作,像增加或提取数据等。
- 通过监听正确类型的 DOM 事件以等待操作完成。
- 在操作结果上进行一些操作(可以在 request 对象中找到)
同样是因为它提供的API比较底层,操作较为繁琐,有许多第三方库对其进行了封装,使用较广泛的是idb和idb-keyval。
在实际使用中,如果我们使用indexedDB的目的仅仅是为了它能存储对象,或是因为它的存储大小,而不聚焦于巨量数据的高性能搜索,我们并不需要用到它全部的功能,这时候idb-keyval最适合不过。
idb-keyval这个第三方库将indexedDB化简为了仅通过get和set就能以类似Web Storage的形式存取数据。
idb和idb-keyval出自同一个作者,如果想要使用索引的功能,就需要使用idb这个库,它包含了indexedDB的所有功能,并且也简化了原生indexedDB复杂的操作。
总结
- Cookie 的本职工作并非本地存储,而是“维持状态”,主要是服务器进行set-cookie
- Web Storage提供了浏览器本地缓存的能力,数据量小时推荐使用
- IndexedDB用于客户端存储大量结构化数据,当Web Storage不能满足需求时使用
参考文章
https://zzzmh.cn/single?id=118
https://www.ruanyifeng.com/blog/2018/07/indexeddb.html
https://github.com/jakearchibald/idb
https://github.com/jakearchibald/idb-keyval
https://www.cnblogs.com/fundebug/p/about-browser-storage.html
https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API/Using_IndexedDB