让网站离线也能运行——离线存储。让 IndexedDB 成为关键!
执行
例子
应用场景?
注意:本文不假设您已了解第一部分的任何内容。
传统上,Cookie 用于存储本地数据。但随着 HTML5 API 的出现,我们有了新的选择,例如 DataFrame localStorage、sessionStorageDatabase、WebSQLDatabase 和IndexedDBDataFrame。本文将重点讨论 IndexedDB。
假设你已经完成了 Service Worker 的配置,现在你的网站可以在离线状态下加载。但是……如果你想存储和检索特定数据怎么办?fetch()由于用户处于离线状态,你不能直接通过 API 来实现。
在这种情况下,您可以将数据存储在 IndexedDB 中!
索引数据库API(Indexed Database API)是由Web浏览器提供的一种JavaScript应用程序编程接口,用于管理JSON对象的NoSQL数据库。它是由万维网联盟(W3C)维护的标准。
~维基百科
IndexedDB 由浏览器提供,因此无需联网即可执行 CRUD(创建、读取、更新、删除)操作。它类似于 Android 中的 SQLite(只是不包含 SQL 语句)。
执行
如果您更喜欢通过 codesandbox 自学,可以查看IndexedDB 示例。
对于使用前缀的浏览器,我们可以从类似这样的内容开始:
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction || {READ_WRITE: "readwrite"};
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
if (!window.indexedDB) {
console.log("Your browser doesn't support a stable version of IndexedDB. Such and such feature will not be available.");
}
在继续讲解下一段代码之前,我想先提醒大家一点:IndexedDB 本身并没有使用Promise,因此它很大程度上依赖于onsuccess回调onerror函数。虽然有一些库(例如idb)提供了 Promise 化的 IndexedDB 版本,但本文将使用原生的 IndexedDB 代码。
打开/创建数据库
打开数据库时,如果数据库不存在,则会自动创建新数据库。
let db;
const request = indexedDB.open("MyTestDatabase");
request.onsuccess = function(event) {
db = event.target.result;
};
定义模式/值
创建新数据库时,onupgradeneeded会触发该事件。我们可以在这里创建对象存储。
request.onupgradeneeded = function() {
const db = event.target.result;
const userObjectStore = db.createObjectStore("users", {keyPath: "userid"});
userObjectStore.createIndex("name", "name", { unique: false });
userObjectStore.createIndex("email", "email", { unique: true });
}
因此,创建/打开数据库的完整代码大致如下所示:
async function openDatabase() {
return new Promise((resolve, reject) => {
const request = indexedDB.open("MyTestDatabase");
request.onsuccess = function(event) {
resolve(event.target.result);
}
request.onupgradeneeded = function() {
const db = event.target.result;
const userObjectStore = db.createObjectStore("users", {keyPath: "userid"});
userObjectStore.createIndex("name", "name", { unique: false });
userObjectStore.createIndex("email", "email", { unique: true });
}
})
}
openDatabase()
.then(db => {
// db instance accessible here
})
添加数据
现在我们已经可以db在 Promise 中访问对象了openDatabase()。我们可以使用此对象向 IndexedDB 添加/读取/删除数据。
(async function() {
const db = await openDatabase();
// Add
const userReadWriteTransaction = db.transaction("users", "readwrite");
const newObjectStore = userReadWriteTransaction.objectStore("users");
newObjectStore.add({
userid: "4",
name: "John Doe",
email: "josn@gmail.com"
});
userReadWriteTransaction.onsuccess = function(e) {
console.log("Data Added");
}
})();
数据
const request = db.transaction("users", "readwrite")
.objectStore("users")
.delete("4");
request.onsuccess = function(event) {
console.log("Deleted!");
};
读取和更新数据
const readTransaction = db.transaction(["users"]);
const objectStore = transaction.objectStore("customers");
const request = objectStore.get("4");
request.onsuccess = function(event) {
console.log("User is " + request.result.name);
const data = event.target.result;
data.name = "John Doe";
const updateRequest = objectStore.put(data);
updateRequest.onsuccess = function(event) {
console.log("Data Updated!");
}
};
例子
应用场景?
-
如果你的 API 总是(或大多数时候)返回相同的值,你可以调用 API,将响应存储在 IndexedDB 中,下次用户调用 API 时,你可以直接从 IndexedDB 返回该值,之后或许可以再次调用 API 并存储更新后的值。
-
我的应用PocketBook使用了 IndexedDB,它是 Google Keep 的替代品,可以用来存储待办事项、目标等等。PocketBook 默认使用 IndexedDB 来存储笔记本信息。因此,即使离线也可以使用 PocketBook!
MDN 文档: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB
CodeSandbox 示例: https://codesandbox.io/s/indexeddb-example-trv2f
PocketBook: https: //pocketbook.cc
感谢阅读!如果您有任何使用 IndexedDB 的有趣项目,请在下方留下链接!
文章来源:https://dev.to/saurabhdaware/make-websites-work-offline-offline-storage-making-indexeddb-the-hero-1oee