浏览器存储运用十分广泛,保存登录信息,用户数据,构建web离线应用,打开chrome控制台,点击application,可以看到storage项中包含的就是chrome支持的前端存储技术了,下面我们介绍其中的三种:localStorage、sessionStorage、IndexedDB
localStorage
localStorage中存储的数据是无期限的,当页面关闭时,数据不会被清除。localStorage的中的数据是有“作用域”的,比如www.baidu.com无法显示和操作www.talkmoney.cn域名下的localStorage。 使用localStorage存储数据非常简单,一下两种方式是等价的。
localStorage.demo = 'value';
localStorage.setItem('demo2', 'value2');
从localStorage中取出数据也非常简单,以下方法也验证了存储数据的两种方法是等价的。取出数据的两种方法,当数据中不包含改键值的数据时,返回值不同。
console.log(localStorage.demo); // "value"
console.log(localStorage.getItem('demo')); // "value"
console.log(localStorage.demo2); // "value2"
console.log(localStorage.getItem('demo2')); // "value2"
console.log(localStorage.demo3); // undefined
console.log(localStorage.getItem('demo3')); // null
length
localStorage.length
表示localStorage中存储了多少数据项,使用上述两种方法增加数据项,改属性的值都会相应的增加。
removeItem(..)
移除特定项,参数是键值,该方法没有返回值。
console.log(localStorage.removeItem('demo2'))
clear()
清除所有数据项localStorage.clear()
。
key(..)
由索引获得键名,未找到时返回null
。
console.log(localStorage.key(1)); // "demo"
console.log(localStorage.key(3)); // null
sessionStorage
sessionStorage
与localStorage
相似,不同的是localStorage
中存储的数据没有时间限制,但是存储在sessionStorage
中的数据会在页面关闭后被清除。
sessionStorage
有和localStorage
同样的api
,并且他们的“作用域”限制也相同,数据仅限当前域名下查看和操作。
indexedDB
人们对于web应用的能力需求越来越高,前端的业务场景也越来越丰富,导致大型web应用开始考虑将数据存储在客户端。
上面讲到的localStorage
通常存储空间在2.5MB到10MB之间,提供的api少,对于小型的前端场景几乎能处理,但是如果牵涉到大量数据,就有点力不从心了。
indexedDB
就是处理这类业务场景的本地数据库,他除了能存储比localStorage
更多的数据外,还提供了查找接口,还能建立索引。indexedDB
不是关系型数据库,更接近NoSQL数据库,也有人将他成为事务型数据库。
学习indexedDB的使用,首先要清楚他的各种接口对象,以下是几个重要的接口对象:
- 数据库:IDBDatabase 对象
- 对象仓库:IDBObjectStore 对象
- 索引: IDBIndex 对象
- 事务: IDBTransaction 对象
- 操作请求:IDBRequest 对象
- 指针: IDBCursor 对象
- 主键集合:IDBKeyRange 对象
从示例出发
接下来用实际操作来体会indexedDB
提供的API
,如何操作,以及返回的什么。
打开数据库
let request = indexedDB.open('databaseName', '1');
open(..)
方法接受两个参数,第一个参数是数据库名,第二个参数是数据库版本。默认为1,如果数据库不存在,则会新建数据库。version
为1.1
和1
是一样的。
该方法返回一个IDBRequest
对象而不是直接返回一个数据库对象,你需要监听IDBRequest
对象上的事件才能拿到数据库对象。
let db;
request.onsuccess = function () {
db = request.result;
console.log(db instanceof IDBDatabase); // true
};
新建存储空间
通常我们再新建数据库和升级数据库版本时会新建对象仓库(类似MySQL中的表)
request.onupgradeneeded = function() {
db = request.result;
let objectStore = db.createObjectStore('date', { keyPath: 'id' });
};
// 没有合适的主键时可以让indexedDB自动生成主键
let objectStore = db.createObjectStore('date', { autoIncrement: true });
以上代码建立了一个叫person
的存储空间(对象仓库),主键是id
。
request
还有error
事件。
插入数据
indexedDB的中对于数据的修改是通过事物完成的,将这种过程一步一步写下来,可能有些麻烦,就像下面这样:
// 开启一个事务,指定要处理的对象仓库名和操作模式,操作模式分为‘readonly’和‘readwrite’
let transaction = db.transaction(['date'], 'readwrite')
// 从事务中获取对象仓库:IDBObjectStore
let store = transaction.objectStore('date')
// 插入数据,返回的是一个请求对象,监听上面的事件可以获取插入结果
let request = store.add({id: 1, date: new Date()})
request.onsuccess = function () {
console.log('数据写入成功');
};
request.onerror = function () {
console.log('数据写入失败');
}
// 实际上事务也有事件的
transaction.oncomplete = function () {
console.log('all done');
}
在没有特殊要求的情况下,可以一步到位的写法
let request = db.transaction(['date'], 'readwrite').objectStore('date').add({id: 1, date: new Date()})
读取数据
读取数据也是通过事务完成的。
let request = db.transaction(['date'], 'readwrite').objectStore('date').get(1);
request.onsuccess = function () {
let {
date
} = request.result;
console.log(`date: ${date}`);
}
查询数据还可以使用objectStore.getAll()
。
更新数据和删除数据
增删改查的api都相似
// 修改数据
let request = db
.transaction(['date'], 'readwrite')
.objectStore('date')
.put({id: 1, date: new Date(), lastest: true});
// 删除数据
let request = db
.transaction(['date'], 'readwrite')
.objectStore('date')
.delete(2);
作者简介:叶茂,芦苇科技web前端开发工程师,代表作品:口红挑战网红小游戏、服务端渲染官网。擅长网站建设、公众号开发、微信小程序开发、小游戏、公众号开发,专注于前端领域框架、交互设计、图像绘制、数据分析等研究。 一起并肩作战: yemao@talkmoney.cn 访问 www.talkmoney.cn 了解更多