前端数据持久化存储方案
Youky ... 2021-10-11 About 3 min
# 总览
技术 | 有效时长 | 存储内容 | 容量限制 | 不同 tab 页能否共享 | 作用域 |
---|---|---|---|---|---|
cookie | 关闭页面前 | 字符串 | 几 K | √ | 当前路径及其子路径 |
sessionStorage | 关闭页面前 | 字符串 | 几 M | × | 当前标签页 |
localStorage | 永久 | 字符串 | 几 M | √ | 同源策略 |
indexedDB | 永久 | 多种类型 | 无 | √ | 同源策略 |
localForage | 永久 | 多种类型 | 取决于浏览器兼容性 | √ |
同源策略:相同的协议、主机名、端口
# cookie
服务器为了识别用户而存储在用户本地的文件。以键值对形式存储在本地,在浏览器请求相应web 页面的时候携带在 HTTP 头中
# 缺点
- 可能被禁用
- 与浏览器相关。同一个用户用不同浏览器访问同一个页面的数据不能互通
- 可能被用户删除
- 安全性没有保障,因为是以纯文本保存的,信息需要事先加密
- 性能缺陷:cookie 和域名绑定,不管其下的某个子地址是否需要,都会携带
# 操作 API
在 JS 中利用 document.cookie 进行操作
# 创建 & 修改
document.cookie =
"userName=xxx; age=xx; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/";
1
2
2
- 开头的键值对表示 cookie 的内容,可以包含多个键值对
- expires 表示过期时间(以 UTC 或 GMT 时间)。默认在浏览器关闭时删除
- path 表示 cookie 对应的路径。默认为当前页面
修改方式和创建相同,即对同名的键重新赋值将旧的值覆盖。 注意:多次为 document.cookie 赋值,新的键值对会添加到原本的键值对之中,而不会直接覆盖
# 读取
// 返回所有cookie键值对:userName=xxx; age=xx;
const str = document.cookie;
1
2
2
# 删除
不必显式删除,将有效时间改为过去即可。
document.cookie = "userName; expires=Thu, 18 Dec 2000 12:00:00 GMT; path=/";
1
# sessionStorage & localStorage
# 特点
- 都是全局对象 window 的属性。在本地创建键值对存储数据
- 操作的 API 基本相同
- 有效时间不同:
- localStorage 有效期为永久,除非手动删除
- sessionStorage 有效期为窗口打开期间。关闭时自动清除
# 缺点
- 存储容量受限,一般只有几 M
- 仅支持字符串,存储对象时需要转换
- 读取是同步的。可能出现延迟影响用户体验
# 操作 API
# 创建 & 修改
localStorage.setItem("key", "someValue");
// 或直接用等号赋值
localStorage.key = "someValue";
1
2
3
4
2
3
4
修改方式即同名覆盖
# 读取
const value = localStorage.getItem("key", "someValue");
// 或直接读取属性名
const value = localStorage.key;
1
2
3
4
2
3
4
# 删除
- 删除某一个键值对
localStorage.removeItem("key");
1
- 清空所有键值对
localStorage.clear();
1
# indexedDB
- 一种非关系型数据库,存储的内容不再受字符串类型的限制,同时大小也不再受限。
- 支持异步读写。
由于其 API 需要额外的学习成本,使用localForage进行操作即可。
# localForage
- 智能的存储方案:indexedDB -> WebSQL -> localStorage,优先级从高到低,保证了兼容所有主流浏览器
- 异步 API,支持回调函数形式和 Promise 形式
- 读取、创建、删除等 API 都与 localStorage 相同
# 遍历所有键值对
localforage
.iterate(function(value, key, iterationNumber) {
// 此回调函数将对所有 key/value 键值对运行
console.log([key, value]);
})
.then(function() {
console.log("Iteration has completed");
})
.catch(function(err) {
// 当出错时,此处代码运行
console.log(err);
});
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12