存储
有几种方式可以实现存储功能,分别有什么优缺点?
特性 | cookie | localStorage | sessionStorage | indexDB |
---|---|---|---|---|
数据生命周期 | 一般由服务器生成,可以设置过期时间 | 除非被清理,否则一直存在 | 页面关闭就清理 | 除非被清理,否则一直存在 |
数据存储大小 | 4K | 5M | 5M | 无限 |
与服务端通信 | 每次都会携带在 header 中,对于请求性能影响 | 不参与 | 不参与 | 不参与 |
从上表可以看到,cookie
已经不建议用于存储。如果没有大量数据存储需求的话,可以使用 localStorage
和 sessionStorage
。对于不怎么改变的数据尽量使用 localStorage
存储,否则可以用 sessionStorage
存储。
对于 cookie
来说,我们还需要注意安全性。
属性 | 作用 |
---|---|
value | 如果用于保存用户登录态,应该将该值加密,不能使用明文的用户标识 |
http-only | 不能通过 JS 访问 Cookie,减少 XSS 攻击 |
secure | 只能在协议为 HTTPS 的请求中携带 |
same-site | 规定浏览器不能在跨域请求中携带 Cookie,减少 CSRF 攻击 |
localStorage
indexDB
基本概念
关系型数据库
- 数据库 Database
- 数据表 Table(IndexedDB 中叫 ObjectStore)
- 字段 Field
- 事务 Transaction
增、删、改、查这些操作,都需要通过事务 Transaction 来完成
- 如果事务中任何一个操作没有成功,整个事务都会回滚
- 在事务完成之前,操作不会影响数据库
- 不同事务之间不能互相影响
基本使用
使用 indexedb 第一步需要打开数据库
jsx
const request = indexedDB.open('mondo')
数据库存在版本(version)概念,连接时也可以指定版本
jsx
const version = 1
const request = indexedDB.open('mondo', version)
打开 mondo
数据库,没有时,自动创建。打开后,request
挂载几个回调函数
jsx
var db; // 全局 indexedDB 数据库的实例
request.onupgradeneeded = function (event) {
db = event.target.result;
console.log('版本更新');
};
request.onsuccess = function (event) {
db = request.result;
console.log('数据库连接成功')
};
request.onblocked = function (event) {
console.log('数据库被阻止!')
}
request.onerror = function (event) {
console.log('连接失败!');
};
onupgradeneeded
在版本改变时触发- 注意首次连接数据库时,版本从 0 变成 1,因此也会触发,且先于
onsuccess
onsuccess
在连接成功后触发onerror
在连接失败时触发onblocked
在连接被阻止的时候触发,比如打开版本低于当前存在的版本
由于这个四个都是异步操作,意味着连接数据库后,需要等待部分时间后,才能在进行操作,如果想创建一张表,必须在 onupgradeneeded
回调里面执行操作。
jsx
request.onupgradeneeded = function (event) {
db = event.target.result;
console.log('版本更新');
if (!db.objectStoreNames.contains('user')) {
db.createObjectStore('user', {
keyPath: 'id', // 主键
autoIncrement: true, // 自增
})
}
};
上面这段代码,在数据库初始化时,创建了一个 user
的表,并且以 id
为自增主键(每加一条数据,主键会自动增长,无需开发者指定)
jsx
request.onsuccess = function (event) {
db = request.result;
console.log('数据库连接成功')
const adding = db.transaction('user', 'readwrite')
.objectStore('user')
.add({ name: 'mondo', age: 32 });
adding.onsuccess = function (event) {
console.log('写入成功')
}
adding.onerror = function (event) {
console.log('写入失败')
}
};
在数据库连接成功后,可以对表进行数据增、删、改、查操作。
如果需要查数据,需要创建一个 readonly
的事务。
相关应用: