喔唷网 - 网络从业者技术信息综合门户!

当前位置: 主页 > 教程技术 > 编程语言 > html/css

HTML5 IndexedDB简介 9.2

时间 : 2025-04-27 10:19来源 : 喔唷网作者 : 喔唷教程点击 :
1. 核心概念与特点 定义:IndexedDB 是浏览器提供的一种底层 API,用于客户端存储大量结构化数据(如 JSON 对象、文件二进制数据等)。支持高性能的索引查询、事务操作,适合复杂场景。 核心特性:

1. 核心概念与特点

  • 定义:IndexedDB 是浏览器提供的一种底层 API,用于客户端存储大量结构化数据(如 JSON 对象、文件二进制数据等)。支持高性能的索引查询、事务操作,适合复杂场景。
  • 核心特性:键值存储:数据以键值对形式存储,键可自定义或自动生成。事务支持:保证数据操作的原子性和一致性。异步 API:所有操作均为异步,避免阻塞主线程。索引查询:可对数据字段创建索引,实现快速检索。大容量存储:通常支持数百 MB 至数 GB 数据(具体由浏览器决定)。
  • 与 Web Storage 对比:特性Web StorageIndexedDB数据结构简单键值对结构化数据(对象/二进制)查询能力仅按键查询支持索引、范围查询、游标事务无支持原子事务容量~5MB大(通常 >250MB)适用场景简单配置/临时数据复杂应用、离线缓存

2. 基本使用流程

打开/创建数据库:使用 indexedDB.open(databaseName, version) 打开数据库,若不存在则自动创建。

const request = indexedDB.open('MyDatabase', 1);

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

request.onsuccess = (event) => {
  const db = event.target.result;
  console.log('数据库已打开:', db);
};

// 首次创建或版本升级时触发
request.onupgradeneeded = (event) => {
  const db = event.target.result;
  // 创建对象存储空间(类似表)
  const store = db.createObjectStore('books', {
    keyPath: 'id',  // 主键字段
    autoIncrement: true
  });
  // 创建索引(允许按书名查询)
  store.createIndex('by_title', 'title', { unique: false });
};

事务操作:所有数据操作需在事务中进行,事务分为只读(readonly)和读写(readwrite)。

const transaction = db.transaction('books', 'readwrite');
const store = transaction.objectStore('books');

// 添加数据
store.add({ title: 'JavaScript权威指南', author: 'David Flanagan' });

// 查询数据(通过主键)
const getRequest = store.get(1);
getRequest.onsuccess = (event) => {
  console.log('查询结果:', event.target.result);
};

// 通过索引查询
const index = store.index('by_title');
const indexRequest = index.get('JavaScript权威指南');
indexRequest.onsuccess = (event) => {
  console.log('索引查询结果:', event.target.result);
};

3. 高级功能

游标遍历:使用游标遍历对象存储中的所有数据。

const cursorRequest = store.openCursor();
cursorRequest.onsuccess = (event) => {
  const cursor = event.target.result;
  if (cursor) {
    console.log('当前数据:', cursor.value);
    cursor.continue(); // 继续下一个
  } else {
    console.log('遍历完成');
  }
};

范围查询:利用 IDBKeyRange 定义查询范围。

// 查询主键在 10 到 20 之间的数据
const range = IDBKeyRange.bound(10, 20);
const rangeRequest = store.openCursor(range);

存储二进制数据:IndexedDB 支持存储 ArrayBuffer 或 Blob。

const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', (event) => {
  const file = event.target.files[0];
  const reader = new FileReader();
  reader.onload = (e) => {
    const buffer = e.target.result;
    store.add({ id: 1, fileName: file.name, data: buffer });
  };
  reader.readAsArrayBuffer(file);
});

4. 错误处理与调试

错误捕获:通过监听事务和请求的 error 事件处理异常。

transaction.onerror = (event) => {
  console.error('事务失败:', event.target.error);
};

store.add(data).onsuccess = () => {
  console.log('数据添加成功');
};

浏览器开发者工具:Chrome/Firefox 开发者工具中可直接查看和编辑 IndexedDB 数据(Application/Storage 面板)。

5. 使用场景

  • 离线应用:缓存大量数据供离线使用(如文档编辑器、邮件客户端)。
  • 复杂查询需求:需要按多个字段快速检索的场景(如商品库按价格、分类筛选)。
  • 大文件缓存:存储图片、音频等二进制资源。

6. 最佳实践

封装工具库:使用轻量级库(如 Dexie.js 简化 API 调用:

const db = new Dexie('MyDatabase');
db.version(1).stores({
  books: '++id, title, author'  // 定义主键和索引
});

// 添加数据
await db.books.add({ title: 'Eloquent JavaScript', author: 'Marijn Haverbeke' });

// 查询数据
const books = await db.books.where('author').equals('Marijn Haverbeke').toArray();

版本迁移:在 onupgradeneeded 中处理数据库结构变更(如新增索引)。

request.onupgradeneeded = (event) => {
  const db = event.target.result;
  if (!db.objectStoreNames.contains('users')) {
    const store = db.createObjectStore('users', { keyPath: 'email' });
    store.createIndex('by_age', 'age');
  }
};

性能优化:避免在单个事务中处理过多数据。使用游标分批读取大数据集。


7. 示例:简易待办事项应用

<input type="text" id="taskInput" placeholder="输入任务">
<button onclick="addTask()">添加任务</button>
<ul id="taskList"></ul>

<script>
  let db;
  const request = indexedDB.open('TodoDB', 1);

  request.onupgradeneeded = (event) => {
    db = event.target.result;
    const store = db.createObjectStore('tasks', {
      keyPath: 'id',
      autoIncrement: true
    });
    store.createIndex('by_status', 'completed');
  };

  request.onsuccess = (event) => {
    db = event.target.result;
    loadTasks();
  };

  function addTask() {
    const taskInput = document.getElementById('taskInput');
    const task = {
      text: taskInput.value,
      completed: false,
      createdAt: new Date()
    };

    const transaction = db.transaction('tasks', 'readwrite');
    const store = transaction.objectStore('tasks');
    store.add(task);

    transaction.oncomplete = () => {
      taskInput.value = '';
      loadTasks();
    };
  }

  function loadTasks() {
    const taskList = document.getElementById('taskList');
    taskList.innerHTML = '';

    const transaction = db.transaction('tasks', 'readonly');
    const store = transaction.objectStore('tasks');
    const cursorRequest = store.openCursor();

    cursorRequest.onsuccess = (event) => {
      const cursor = event.target.result;
      if (cursor) {
        const li = document.createElement('li');
        li.textContent = cursor.value.text;
        taskList.appendChild(li);
        cursor.continue();
      }
    };
  }
</script>

8. 安全与隐私

  • 同源策略:IndexedDB 数据库仅允许同源页面访问。
  • 用户隐私:用户可随时通过浏览器设置清除数据库。
  • 数据加密:敏感数据建议在存储前加密(如使用 Web Crypto API)。

通过以上内容,可全面掌握 IndexedDB 的核心概念、使用方法及实际开发技巧,适用于需要处理复杂数据结构的现代 Web 应用。

栏目列表

关联类容

热点推荐

栏目推荐

猜你喜欢