# 本地缓存

本文搬运自:浏览器的本地存储有哪些?各自优劣如何? (opens new window)

浏览器的本地存储主要分为 CookieWebStorageIndexDB, 其中 WebStorage 又可以分为 localStoragesessionStorage。接下来我们就来一一分析这些本地存储方案。

# Cookie

# 语法

// 读取所有可从当前location访问的Cookie
allCookies = document.cookie;

Cookie 最开始被设计出来其实并不是来做本地储存的,而是为了弥补 HTTP状态管理上的不足

HTTP 协议是一个无状态协议,客户端向服务端发请求,服务端返回响应,故事就这样结束了,但是下次发请求如何让服务端知道客户端是谁呢?

这种背景下,就产生了 Cookie

Cookie 本质上就是浏览器里面存储的一个很小的文件,内部以键值对的方式来存储。向同一个域名下发送请求,都会携带相同的 Cookie,服务端拿到 Cookie 进行解析,便能拿到客户端的状态。

Cookie 的作用很好理解,就是用来做状态存储的,但它也是有诸多致命的缺陷的:

  1. 容量缺陷:Cookie 的体积上限只有 4KB,只能用来存储少量的信息。
  2. 性能缺陷:Cookie 紧跟域名,不管域名下面的某一个地址需要不需要这个 Cookie,请求都会携带上完整的 Cookie,这样随着请求数的增多,其实会造成巨大的性能浪费,因为请求携带了很多不必要的内容。
  3. 安全缺陷:由于 Cookie 以纯文本的形式在浏览器和服务器中传递,很容易被非法用户截获,然后进行一系列的篡改,在 Cookie 的有效期内重新发送给服务器,这是相当危险的。另外,在 HttpOnlyfalse 的情况下,Cookie 信息能直接通过 js 脚本来读取。

# localSorage

localStorage 有一点跟 Cookie 一样,就是针对一个域名,即在同一个域名下,会存储相同的一段localStorage
不过它相对 Cookie 还是有相当多的区别的:

  1. 容量:localStorage 的容量上限为 5M,相比于 Cookie4K 大大增加。当然这个 5M 是针对一个域名的,因此对于一个域名是持久存储的。
  2. 只存在客户端:默认不参与与服务端的通信。这样就很好地避免了 Cookie 带来的性能问题安全问题
  3. 接口封装:通过 localStorage 暴露在全局,并通过它的 setItemgetItem 等方法进行操作,非常方便。

# 操作方式

接下来我们来具体看看如何操作 localStorage

let obj = { name: 'sanyuan', age: 18 };
localStorage.setItem('name', 'sanyuan');
localStorage.setItem('info', JSON.stringify(obj));

接着进入相同的域名时就能拿到相应的值:

let name = localStorage.getItem('name');
let info = JSON.parse(localStorage.getItem('info'));

从这里可以看出,localStorage 其实存储的都是字符串,如果是存储对象需要调用 JSON.stringify 方法,并且用 JSON.parse 来解析成对象。

# 应用场景

利用 localStorage 的较大容量和持久特性,可以利用 localStorage 存储一些内容稳定的资源,比如官网的 logo,存储 Base64 格式的图片资源,因此利用 localStorage

# sessionStorage

# 特点

sessionStorage 以下方面和 localStorage 一致:

  • 容量:容量上限也为 5M
  • 只存在客户端:默认不参与与服务端的通信。
  • 接口封装:除了 sessionStorage 名字有所变化,存储方式、操作方式均和 localStorage 一样。

sessionStoragelocalStorage 又一个本质区别,那就是前者只是会话级别但存储,并不是持久化存储。会话结束,也就是页面关闭,这部分 sessionStorage 就不复存在了。

# 应用场景

  1. 可以用它对表单信息进行维护,将表单信息存储在里面,可以保证页面即时刷新也不会让之前的表单信息丢失。
  2. 可以用它存储本次浏览记录。如果关闭页面后不需要这些记录,用 sessionStorage 就再适合不过了。事实上微博就采取了这样的存储方式。

# IndexDB

IndexDB 是运行在浏览器中的非关系型数据库,本质上是数据库,绝不是和刚才 WebStorage 的 5M 一个量级,理论上这个容量是没有上限的。
关于它的使用,文本侧重原理,而且 MDN 上的教程文档已经非常详尽,这里就不做赘述来,感兴趣的可以看一下使用文档 (opens new window)

接着我们来分析一些 IndexDB 的一些重要特性,除了拥有数据库本身的特性,比如支持事物存储二进制数据,还有这样一些特性需要格外注意:

  1. 键值对存储:内部采用对象仓库存放数据,在这个对象仓库中数据采用键值对的方式来存储。
  2. 异步操作:数据库的读写属于 I/O 操作,浏览器中对异步 I/O 提供了支持。
  3. 受同源策略限制:即无法访问跨域的数据库。

# 总结

浏览器中各种本地存储和缓存技术的发展,给前端应用带来了大量的机会,PWA 也正是依托了这些优秀的存储方案才得以发展起来。重新梳理一下这些本地存储方案:

  1. cookie 并不适合存储,而且存在非常多的缺陷。
  2. Web Storage 包括 localStoragesessionStorage,默认不会参与和服务器通信。
  3. IndexDB 为运行在浏览器上的非关系型数据库,为大型数据的存储提供了接口。