
window.indexedDB.databases() 在部分浏览器(如 Safari、旧版 Chrome/Firefox)中未实现,直接调用会抛出同步 TypeError;需先检测方法是否存在,再安全执行 Promise,否则 catch 无法捕获该错误。
`window.indexeddb.databases()` 在部分浏览器(如 safari、旧版 chrome/firefox)中未实现,直接调用会抛出同步 typeerror;需先检测方法是否存在,再安全执行 promise,否则 `catch` 无法捕获该错误。
indexedDB.databases() 是一个实验性 API,用于异步获取当前 Origin 下所有已打开 IndexedDB 数据库的元信息(如名称、版本),但并非所有浏览器都支持该方法。例如:
- ✅ Chrome 89+、Firefox 100+、Edge 93+ 支持
- ❌ Safari 全版本(截至 Safari 17.6)、Chrome 完全不支持,调用
indexedDB.databases会返回undefined,进而导致undefined is not a function错误。
你原代码的问题在于:
(window.indexedDB.databases()).then(...) // ❌ 同步报错,Promise 尚未创建!
indexedDB.databases 本身不存在时,window.indexedDB.databases() 这一表达式在进入 .then() 前就已抛出 TypeError,属于同步异常,因此 .catch() 完全无效。
✅ 正确做法是:先检查方法是否存在,再调用,并统一处理 Promise 链与同步错误:
function dbReady(dbName, callback) {
// 1. 环境与 API 可用性检查
if (typeof window === "undefined" || !window.indexedDB || typeof window.indexedDB.databases !== 'function') {
// 不支持时,降级为「尝试打开 + onupgradeneeded」逻辑(更可靠)
const request = indexedDB.open(dbName);
request.onsuccess = () => {
request.result.close(); // 立即关闭,仅验证可打开
if (typeof callback === 'function') callback(true);
};
request.onerror = () => {
if (typeof callback === 'function') callback(false);
};
request.onupgradeneeded = () => {
// DB 不存在时会触发,说明需创建 → 视为“不存在”
if (typeof callback === 'function') callback(false);
};
return;
}
// 2. 支持 databases():安全调用
window.indexedDB.databases()
.then(dbs => {
const exists = dbs.some(db => db.name === dbName);
if (typeof callback === 'function') callback(exists);
return exists;
})
.catch(err => {
console.warn('indexedDB.databases() failed (fallback triggered):', err);
// 回退到 open 检测逻辑(同上)
const request = indexedDB.open(dbName);
request.onsuccess = () => {
request.result.close();
if (typeof callback === 'function') callback(true);
};
request.onerror = () => {
if (typeof callback === 'function') callback(false);
};
request.onupgradeneeded = () => {
if (typeof callback === 'function') callback(false);
};
});
}
? 关键注意事项:
- 不要依赖
databases()作为唯一判断依据——它不可靠且非标准(MDN 标记为“非规范”); - 生产环境推荐使用
indexedDB.open()+onupgradeneeded事件判断数据库是否存在:若触发onupgradeneeded且event.oldVersion === 0,说明数据库尚不存在; - 若需精确区分“数据库存在但未打开”与“完全不存在”,可结合
databases()(支持时)与open().onsuccess(兜底)双策略; - 避免在
.then()外层包裹无意义的匿名函数:原代码中then(dbs => function(dbs) {...})属于语法错误(函数未被调用),应改为then(dbs => { ... })。
总之,浏览器 API 兼容性是前端存储开发的常见陷阱。始终优先检测能力(feature detection),而非假设存在——这是健壮 IndexedDB 应用的第一道防线。










