浏览器存储运用十分广泛,保存登录信息,用户数据,构建web离线应用,打开chrome控制台,点击application,可以看到storage项中包含的就是chrome支持的前端存储技术了,下面我们介绍其中的三种:localStorage、sessionStorage、IndexedDB

chrome中的前端存储技术

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

sessionStoragelocalStorage相似,不同的是localStorage中存储的数据没有时间限制,但是存储在sessionStorage中的数据会在页面关闭后被清除。

sessionStorage有和localStorage同样的api,并且他们的“作用域”限制也相同,数据仅限当前域名下查看和操作。

indexedDB

人们对于web应用的能力需求越来越高,前端的业务场景也越来越丰富,导致大型web应用开始考虑将数据存储在客户端。 上面讲到的localStorage通常存储空间在2.5MB到10MB之间,提供的api少,对于小型的前端场景几乎能处理,但是如果牵涉到大量数据,就有点力不从心了。 indexedDB就是处理这类业务场景的本地数据库,他除了能存储比localStorage更多的数据外,还提供了查找接口,还能建立索引。indexedDB不是关系型数据库,更接近NoSQL数据库,也有人将他成为事务型数据库。

学习indexedDB的使用,首先要清楚他的各种接口对象,以下是几个重要的接口对象:

从示例出发

接下来用实际操作来体会indexedDB提供的API,如何操作,以及返回的什么。

打开数据库

let request = indexedDB.open('databaseName', '1');

open(..)方法接受两个参数,第一个参数是数据库名,第二个参数是数据库版本。默认为1,如果数据库不存在,则会新建数据库。version1.11是一样的。

该方法返回一个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的存储空间(对象仓库),主键是idrequest还有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 了解更多