Skip to content
On this page

存储

有几种方式可以实现存储功能,分别有什么优缺点?

特性cookielocalStoragesessionStorageindexDB
数据生命周期一般由服务器生成,可以设置过期时间除非被清理,否则一直存在页面关闭就清理除非被清理,否则一直存在
数据存储大小4K5M5M无限
与服务端通信每次都会携带在 header 中,对于请求性能影响不参与不参与不参与

从上表可以看到,cookie 已经不建议用于存储。如果没有大量数据存储需求的话,可以使用 localStoragesessionStorage 。对于不怎么改变的数据尽量使用 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('写入失败')
    }
};

在数据库连接成功后,可以对表进行数据增、删、改、查操作。

indexdb.png

如果需要查数据,需要创建一个 readonly 的事务。

相关应用: