跳转到内容

JavaScript IndexedDB

来自代码酷

JavaScript IndexedDB[编辑 | 编辑源代码]

IndexedDB 是浏览器提供的一种客户端数据库解决方案,允许开发者在用户的浏览器中存储大量结构化数据(包括文件/二进制对象)。它是 JavaScript BOM(浏览器对象模型)的重要组成部分,适用于需要离线存储、高性能搜索或处理复杂数据的Web应用。

概述[编辑 | 编辑源代码]

IndexedDB是一种事务型数据库系统,基于键值对存储,支持索引查询。与localStorage相比,它提供:

  • 更大的存储空间(通常为浏览器剩余空间的50%)
  • 异步API(不阻塞UI线程)
  • 事务支持
  • 索引查询能力
  • 存储复杂数据类型

核心概念[编辑 | 编辑源代码]

graph TD A[Database] --> B[Object Store] B --> C[Index] B --> D[Data] A --> E[Transaction] E --> F[CRUD Operations]

  • Database:每个源(origin)可创建多个数据库,通过名称区分
  • Object Store:类似SQL中的表,存储键值对
  • Index:在对象存储上创建的辅助查找结构
  • Transaction:保证数据一致性的操作单元

基本用法[编辑 | 编辑源代码]

打开数据库[编辑 | 编辑源代码]

// 打开或创建数据库
let request = indexedDB.open("MyDatabase", 1);

request.onupgradeneeded = (event) => {
    // 数据库首次创建或版本更新时触发
    let db = event.target.result;
    let store = db.createObjectStore("books", { keyPath: "isbn" });
    store.createIndex("by_title", "title", { unique: false });
};

request.onsuccess = (event) => {
    let db = event.target.result;
    console.log("数据库打开成功");
};

request.onerror = (event) => {
    console.error("数据库打开失败:", event.target.error);
};

添加数据[编辑 | 编辑源代码]

function addBook(db, book) {
    let transaction = db.transaction(["books"], "readwrite");
    let store = transaction.objectStore("books");
    
    let request = store.add(book);
    
    request.onsuccess = () => {
        console.log("书籍添加成功");
    };
    
    request.onerror = (event) => {
        console.error("添加失败:", event.target.error);
    };
}

// 使用示例
let book = {
    isbn: "978-3-16-148410-0",
    title: "JavaScript高级编程",
    author: "John Doe",
    price: 29.99
};
addBook(db, book);

高级特性[编辑 | 编辑源代码]

索引查询[编辑 | 编辑源代码]

function getBookByTitle(db, title) {
    let transaction = db.transaction(["books"], "readonly");
    let store = transaction.objectStore("books");
    let index = store.index("by_title");
    
    let request = index.get(title);
    
    request.onsuccess = (event) => {
        let book = event.target.result;
        console.log("找到书籍:", book);
    };
    
    request.onerror = (event) => {
        console.error("查询失败:", event.target.error);
    };
}

游标遍历[编辑 | 编辑源代码]

function displayAllBooks(db) {
    let transaction = db.transaction(["books"], "readonly");
    let store = transaction.objectStore("books");
    
    let request = store.openCursor();
    
    request.onsuccess = (event) => {
        let cursor = event.target.result;
        if (cursor) {
            console.log("书籍:", cursor.value);
            cursor.continue();
        } else {
            console.log("遍历完成");
        }
    };
}

实际应用案例[编辑 | 编辑源代码]

离线笔记应用[编辑 | 编辑源代码]

1. 用户可以在没有网络连接时创建/编辑笔记 2. 数据存储在IndexedDB中 3. 网络恢复后同步到服务器

媒体资源缓存[编辑 | 编辑源代码]

1. 存储图片/音频等二进制数据 2. 通过IndexedDB的blob支持实现高效缓存 3. 示例代码片段:

function cacheImage(db, url, blob) {
    let transaction = db.transaction("images", "readwrite");
    let store = transaction.objectStore("images");
    
    store.put({
        url: url,
        data: blob,
        timestamp: Date.now()
    });
}

性能优化[编辑 | 编辑源代码]

  • 使用批量操作减少事务开销
  • 合理设置索引提高查询效率
  • 定期清理过期数据
  • 使用Web Worker处理大量数据操作

批量写入示例[编辑 | 编辑源代码]

function bulkAddBooks(db, books) {
    let transaction = db.transaction(["books"], "readwrite");
    let store = transaction.objectStore("books");
    
    books.forEach(book => {
        store.add(book);
    });
    
    transaction.oncomplete = () => {
        console.log("批量添加完成");
    };
}

限制与注意事项[编辑 | 编辑源代码]

  • 同源策略限制
  • 浏览器可能自动删除长时间未使用的数据库
  • 存储空间限制(可用navigator.storage.estimate()查询)
  • 移动设备上性能可能受限

浏览器兼容性[编辑 | 编辑源代码]

几乎所有现代浏览器都支持IndexedDB:

  • Chrome 24+
  • Firefox 16+
  • Edge 12+
  • Safari 10.1+
  • Opera 15+

总结[编辑 | 编辑源代码]

IndexedDB为Web应用提供了强大的客户端存储能力,特别适合:

  • 需要离线功能的PWA应用
  • 处理大量结构化数据
  • 需要复杂查询的场景
  • 存储二进制数据

通过合理设计数据库结构和索引,可以构建高性能的客户端数据层,显著提升用户体验。