indexeddb:part14-troubleshoot

第十四部分:故障排除与调试

问题:indexedDB.open() 报错 原因

  • 浏览器隐私模式限制了 IndexedDB
  • 存储配额已满
  • 浏览器不支持

解决方案

async function safeOpenDB(dbName, version) {
  try {
    // 检测支持性
    if (!window.indexedDB) {
      throw new Error('浏览器不支持 IndexedDB');
    }
 
    // 检测配额
    if (navigator.storage && navigator.storage.estimate) {
      const estimate = await navigator.storage.estimate();
      if (estimate.usage >= estimate.quota) {
        throw new Error('存储空间已满');
      }
    }
 
    return await openDatabase(dbName, version);
  } catch (error) {
    console.error('数据库打开失败:', error);
    // 降级方案
    return new MemoryStorage();
  }
}

问题:TransactionInactiveError 或事务意外中止 原因

  • 在异步操作后继续使用事务
  • 事务中的操作失败导致整体回滚

解决方案

// 错误示例
async function badExample() {
  const transaction = db.transaction(['users'], 'readwrite');
  const store = transaction.objectStore('users');
 
  await fetch('/api/check'); // 异步操作!
 
  store.add(data); // TransactionInactiveError!
}
 
// 正确做法
async function goodExample() {
  // 先准备数据
  const apiData = await fetch('/api/check').then(r => r.json());
 
  // 再开启事务
  const transaction = db.transaction(['users'], 'readwrite');
  const store = transaction.objectStore('users');
 
  store.add({ ...data, ...apiData });
}

问题:ConstraintError: Key already exists 解决方案

// 方案1:使用 put 替代 add
store.put(data); // 覆盖已有记录
 
// 方案2:先检查再插入
const existing = await store.get(key);
if (!existing) {
  store.add(data);
} else {
  console.warn('记录已存在');
}
 
// 方案3:捕获错误
request.onerror = (event) => {
  if (request.error.name === 'ConstraintError') {
    event.preventDefault(); // 阻止事务中止
    console.warn('主键冲突,跳过');
  }
};

Chrome/Edge:

  • F12 → Application → IndexedDB
  • 可查看数据库、对象存储、索引
  • 可查看和删除数据

Firefox:

  • F12 → Storage → IndexedDB
const DEBUG = true;
 
function log(...args) {
  if (DEBUG) {
    console.log('[IndexedDB]', ...args);
  }
}
 
function wrapRequest(request, operation) {
  return new Promise((resolve, reject) => {
    log(`${operation} 开始`);
 
    request.onsuccess = () => {
      log(`${operation} 成功`, request.result);
      resolve(request.result);
    };
 
    request.onerror = () => {
      log(`${operation} 失败`, request.error);
      reject(request.error);
    };
  });
}
错误名 说明 解决方案
AbortError 事务被中止 检查事务逻辑
ConstraintError 违反约束 检查主键/唯一索引
NotFoundError 对象存储不存在 检查名称拼写
QuotaExceededError 存储超限 清理数据或请求持久化
TransactionInactiveError 事务已结束 避免异步后使用事务
VersionError 版本错误 确保版本号递增

本章介绍了 IndexedDB 的故障排除:

  • 常见错误及解决方案
  • 浏览器开发者工具调试方法
  • 日志封装便于排查问题

继续阅读 第十五部分:附录

该主题尚不存在

您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。

  • indexeddb/part14-troubleshoot.txt
  • 最后更改: 2026/04/27 19:55
  • 张叶安