前言
讲到前端存储,可能会想到 cookie、localStorage、sessionStorage、web SQL database(已经凉了)、indexedDB,本文主要讨论的就是indexedDB。
IndexedDB 就是浏览器提供的本地数据库,它可以被网页脚本创建和操作。IndexedDB 允许储存大量数据,提供查找接口,还能建立索引。这些都是 LocalStorage 所不具备的。
通过使用 indexedDB 来写了一个demo,可以通过访问 我的codepen 查看源码
对比
对比 | cookie | localStorage | sessionStorage | indexedDB |
---|---|---|---|---|
存储大小 | 4kb | 5M | 5M | 不少于 250MB,甚至没有上限 |
与服务器端通信 | 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 | 仅在客户端(即浏览器)中保存,不参与和服务器的通信 | ||
生命周期 | 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效 | 除非被清除,否则永久保存 | 仅在当前会话下有效,关闭页面或浏览器后被清除 | 除非被清除,否则永久保存 |
使用场景 | 判断用户是否登录 | 存储一些内容稳定的资源。比如图片内容丰富的电商网站会用它来存储 Base64 格式的图片字符串 | 存储一些当前会话的信息,比如微博的 sessionStorage就主要是存储你本次会话的浏览足迹 | 和 localStorage 用途类似:
|
indexedDB 和 localStorage 兼容性对比
查看工具
👇localStorage
如果你想指定自己的浏览器是什么内核,什么版本的可以通过浏览器版本检测器查看
使用步骤
打开数据库
var request = window.indexedDB.open(databaseName, version);
第一个参数是字符串,表示数据库的名字。如果指定的数据库不存在,就会新建数据库。第二个参数是整数,表示数据库的版本。如果省略,打开已有数据库时,默认为当前版本;新建数据库时,默认为1。
indexedDB.open()方法返回一个 IDBRequest 对象,这个对象通过三种事件error、success、upgradeneeded,处理打开数据库的操作结果。
success 事件表示成功打开数据库,通过 request.result 拿到数据库对象的结果
upgradeneeded 事件 如果指定的版本号,大于数据库的实际版本号,就会发生数据库升级事件upgradeneeded,首次新建数据库也会触发这个事件
打开数据库重点 :
- 拿到数据库对象的结果,如果已经存在
新建数据库
新建对象仓库
(即新建表),指定表名,指定id作为主键
request.onupgradeneeded = function(event) {
db = event.target.result;
var objectStore = db.createObjectStore('person', { keyPath: 'id' ,autoIncrement:true});
}
db.objectStoreNames.contains('person') 可以判断表是否已经存在,如果不存在去创建一张新表
新建索引:objectStore.createIndex('address','address') 索引名称,索引所在的属性
创建数据库的重点:
- 新建对象仓库,相当于表的概念
- 通过对象仓库来新建索引
增数据 objectStore.add
新建一个事务。
新建时必须指定表格名称和操作模式(“只读”或“读写”)。事务的概念非常重要,增删改查的功能都是基于事务来执行的
let transaction = db.transaction('project','readwrite')
let objectStore = transaction.objectStore('project')
let request = objectStore.add(params)
request.onsuccess = function(event){
let result = event.target.result
}
通过事务 transaction.objectStore('project')方法拿到指定对象仓库
(表对象),再通过表对象的 add 方法向表格写入一条数据。
重点:
- 新建一个事务的概念,任何增删改查的操作之前都需要新建事务
- 拿到对象仓库(表对象),然后通过表对象的 add 方法添加数据。
- 写入数据是异步的过程,表对象操作后会返回一个request对象,可以request对象上的 success,error 事件来监听操作是否成功
删 objectStore.delete
都要 新建事务
,所以可以将公共的逻辑抽离出来
const getObjectStore = (db,databaseName)=> {
return new Promise(resolve=>{
const objectStore = db.transaction([databaseName], "readwrite").objectStore(databaseName)
resolve(objectStore)
})
}
// 通过id删除对应数据
let objectStore = getObjectStore(db,'project');
const objectStoreRequest = objectStore.delete(id);
// 删除成功后
objectStoreRequest.onsuccess = function() {
resolve('已删除')
};
查 objectStore.get
let objectStore = getObejectStore(db,'project')
let request = objectStore.get(id)
request.onsuccess = function(event){
// 获取到当前数据
const record = request.result
}
改 objectStore.put
let objectStore = getObejectStore(db,'project')
let request = objectStore.get(id)
request.onsuccess = function(event){
// 获取到当前数据
const record = request.result
// 更新数据库中存储数据
// 需要保持原来数据的指针,所以不采用直接赋值的方式
objectStore.put(Object.assign(record,{newKey1:value1})
}
结尾
上面只介绍了最基础的增删改查的功能,其实 indexedDB是一个比较复杂的 API,涉及不少概念。想了解更多内容,可以查看我下面推荐链接,也可以看我的 codepen源码实例
参考: IndexedDB API