【浏览器原理】浏览器本地存储
浏览器的本地存储主要分为:Cookie、 WebStorage、 IndexedDB。其中WebStorage又可以分为localStorage和sessionStorage。
- cookie 主要用于 “维持状态” 。cookie设计出来的本意是为了弥补HTTP协议在状态管理方面的不足,而非本地存储数据
- Web Storage是专门为浏览器提供的数据存储机制,不与服务端发生通信
- IndexedDB 用于客户端存储大量结构化数据
| Cookie | LocalStorage | SessionStorage | |
|---|---|---|---|
| 大小 | 4Kb | 5Mb | 5Mb |
| 兼容 | H4/H5 | H5 | H5 |
| 访问 | 任何窗口 | 同一窗口 | 同一窗口 |
| 有效期 | 手动设置 | 无 | 直到窗口关闭 |
| 存储位置 | 浏览器和服务器 | 浏览器 | 浏览器 |
| 与请求一起发送 | 是 | 否 | 否 |
| 语法 | 复杂 | 简易 | 简易 |
Cookie
Cookie 最开始被设计出来并不是作为本地存储的,而是为了弥补 HTTP 在状态管理的不足。由于 HTTP 协议是一个无状态协议,客户端向服务器发送请求,服务器返回响应,一次请求过程就结束了。如果下一次发送请求,服务器并不能区分是否是同一个客户端。
Cookie的本质就是存储在浏览器本地的一个很小的文本文件(4kb),内部以键值对的方式来存储信息。在第一次访问网站时,浏览器发出请求,服务器响应请求后,会在响应头(respond header)中添加一个Set-Cookie,并将Cookie放入响应请求中。在之后向同一个域名下发送请求,都会携带相同的 Cookie(造成性能浪费),服务器拿到 Cookie 进行解析,便能拿到客户端的状态。
-
Cookie的缺点
- 容量不足。Cookie 的体积上限只有 4KB,只能用来存储少量的信息。
- 数量有限。每个特定域名下的cookie数量有限,不同浏览器数量限制不同。如果超过数量限制后再设置Cookie,浏览器就会清除以前设置的Cookie(各个浏览器的机制不同)。
- 性能缺陷。每次请求都会携带同域名下的所有 Cookie,造成不必要的性能浪费。
- 安全性差。由于 Cookie 以纯文本的形式在浏览器和服务器中传递,很容易被非法用户截获,然后进行一系列的篡改,在 Cookie 的有效期内重新发送给服务器,这是相当危险的。另外,在 HttpOnly 为 false 的情况下,Cookie 信息能直接通过 JS 脚本来读取。
-
Cookie的属性值
- name:名称,一个唯一确定的cookie的名称,cookie的名称必须经过URL编码。
- value:值,存储在cookie中的字符串值。值必须被URL编码。
- Domain:域,指明cookie对哪个域有效,所有向该域发送的请求都会包含这个信息。
- path:路径,对于指定域中的那个路径,应该向服务器发送cookie。
- Expires/Max-Age:有效期,表示cookie的有效期。
- HttpOnly:如果这个这个值设置为true,就不能通过JS脚本获取cookie的值。通过这个值可以有效防止XSS攻击。
- Secure:安全标志,指定后,cookie只有在使用SSL连接的时候才能发送到服务器。
WebStorage
LocalStorage
localStorage以键值对的方式存储,永久存储,永不失效,除非手动删除。
localStorage有以下几个特点:
-
优点
- 保持的数据永久有效,除非手动删除
- 大小为5M,相比cookie,可以存储更多的信息
- 仅在客户端使用,不和服务端进行通信,因此不用每次请求HTTP都被携带
- 接口封装较好
-
缺点
- 存在浏览器兼容问题,IE8以下版本的浏览器不支持
- 如果浏览器设置为隐私模式,那我们将无法读取到LocalStorage
- LocalStorage受到同源策略的限制,即端口、协议、主机地址有任何一个不相同,都不会访问
-
API:
-
// 设置 localStorage.setItem('name', '张三') localStorage.age = '25' // 取值 localStorage.getItem('name') let age = localStorage.age // 移除 localStorage.removeItem('name') // 移除所有 localStorage.clear()
-
sessionStorage
sessionStorage对象存储特定于某个会话的数据,当这个会话的页签或浏览器关闭,sessionStorage也就消失了。
页面刷新之后,存储在sessionStorage中的数据仍然存在可用
-
sessionStorage的特点:
- 会话级别的浏览器存储
- 大小为5M
- 仅在客户端同一窗口使用,不和服务端通信
- 接口封装较好
-
API
-
// 设置 sessionStorage.setItem('name', '张三') sessionStorage.age = '25' // 取值 sessionStorage.getItem('name') let age = sessionStorage.age // 移除 sessionStorage.removeItem('name') // 移除所有 sessionStorage.clear()
-
IndexedDB
IndexedDB,全称Indexed Database API,是浏览器中保持结构化数据的一种数据库
IndexedDB的思想是创建一套API,方便保存和读取JavaScript对象,同时支持查询和搜索
-
特点
- 键值对存储:IndexedDB采用对象仓库存储数据,可以存储所有类型的数据。仓库中数据以键值对的形式保持。 异步:IndexedDB操作时不会锁死浏览器,用户依然可以进行其他操作。
- 支持事务:有学过数据库的对事务肯定不陌生。事务意味着在一系列操作中,只要有一步失败,整个事务就都取消,数据库回滚到事务执行之前,不存在只改写一部分数据的情况。
- 同源限制:IndexedDB受到同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库。
- 储存空间大: IndexedDB 的储存空间比 localStorage大得多,一般来说不少于 250MB,甚至没有上限。
- 支持二进制储存: IndexedDB不仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)。