Indexed Database API 简称IndexedDB,是浏览器中存储结构化数据的一个方案。IndexedDB 用于代
替目前已废弃的Web SQL Database API。IndexedDB 背后的思想是创造一套API,方便JavaScript 对象的
存储和获取,同时也支持查询和搜索。
IndexedDB 的设计几乎完全是异步的。为此,大多数操作以请求的形式执行,这些请求会异步执行,
产生成功的结果或错误。绝大多数IndexedDB 操作要求添加onerror 和onsuccess 事件处理程序来确
定输出。
2017 年,新发布的主流浏览器(Chrome、Firefox、Opera、Safari)完全支持IndexedDB。IE10/11
和Edge 浏览器部分支持IndexedDB。
数据库
IndexedDB 是类似于MySQL 或Web SQL Database 的数据库。与传统数据库最大的区别在于,
IndexedDB 使用对象存储而不是表格保存数据。IndexedDB 数据库就是在一个公共命名空间下的一组对
象存储,类似于NoSQL 风格的实现。
使用IndexedDB 数据库的第一步是调用indexedDB.open()方法,并给它传入一个要打开的数据
库名称。如果给定名称的数据库已存在,则会发送一个打开它的请求;如果不存在,则会发送创建并打
开这个数据库的请求。这个方法会返回IDBRequest 的实例,可以在这个实例上添加onerror 和
onsuccess 事件处理程序。举例如下:
let db,
request,
version = 1;
request = indexedDB.open(“admin”, version);
request.onerror = (event) =>
alert(Failed to open: ${event.target.errorCode}
);
request.onsuccess = (event) => {
db = event.target.result;
};
以前,IndexedDB 使用setVersion()方法指定版本号。这个方法目前已废弃。如前面代码所示,
要在打开数据库的时候指定版本。这个版本号会被转换为一个unsigned long long 数值,因此不要
使用小数,而要使用整数。
在两个事件处理程序中,event.target 都指向request,因此使用哪个都可以。如果onsuccess
事件处理程序被调用,说明可以通过event.target.result 访问数据库(IDBDatabase)实例了,
这个实例会保存到db 变量中。之后,所有与数据库相关的操作都要通过db 对象本身来进行。如果打
开数据库期间发生错误,event.target.errorCode 中就会存储表示问题的错误码。
对象存储
建立了数据库连接之后,下一步就是使用对象存储。如果数据库版本与期待的不一致,那可能需要
创建对象存储。不过,在创建对象存储前,有必要想一想要存储什么类型的数据。
假设要存储包含用户名、密码等内容的用户记录。可以用如下对象来表示一条记录:
let user = {
username: “007”,
firstName: “James”,
lastName: “Bond”,
password: “foo”
};
观察这个对象,可以很容易看出最适合作为对象存储键的username 属性。用户名必须全局唯一,
它也是大多数情况下访问数据的凭据。这个键很重要,因为创建对象存储时必须指定一个键。
数据库的版本决定了数据库模式,包括数据库中的对象存储和这些对象存储的结构。如果数据库还
不存在,open()操作会创建一个新数据库,然后触发upgradeneeded 事件。可以为这个事件设置处
理程序,并在处理程序中创建数据库模式。如果数据库存在,而你指定了一个升级版的版本号,则会立
即触发upgradeneeded 事件,因而可以在事件处理程序中更新数据库模式。
下面的代码演示了为存储上述用户信息如何创建对象存储:
request.onupgradeneeded = (event) => {
const db = event.target.result;
// 如果存在则删除当前objectStore。测试的时候可以这样做
// 但这样会在每次执行事件处理程序时删除已有数据
if (db.objectStoreNames.contains(“users”)) {
db.deleteObjectStore(“users”);
}
db.createObjectStore(“users”, { keyPath: “username” });
};
这里第二个参数的keyPath 属性表示应该用作键的存储对象的属性名。