
indexedDB.databases() 并非所有浏览器都支持(如 Safari 和旧版 Chrome),直接调用会因方法不存在而抛出同步 TypeError,导致 .catch() 无法捕获;正确做法是先检测方法可用性,再安全调用,并提供降级方案。
`indexeddb.databases()` 并非所有浏览器都支持(如 safari 和旧版 chrome),直接调用会因方法不存在而抛出同步 typeerror,导致 `.catch()` 无法捕获;正确做法是先检测方法可用性,再安全调用,并提供降级方案。
window.indexedDB.databases() 是一个用于异步枚举当前 Origin 下所有 IndexedDB 数据库名称和版本的实用方法,但其浏览器兼容性有限:截至 2024 年,它仅在 Chrome 89+、Edge 89+、Firefox 83+ 中稳定支持,完全不支持 Safari(包括 macOS/iOS)和 Opera Mini 等主流浏览器。因此,像 window.indexedDB.databases() 这样的调用若未加防护,会在不支持的环境中立即触发 TypeError: window.indexedDB.databases is not a function —— 这是一个同步运行时错误,发生在 Promise 构造之前,故 .catch() 完全无效。
✅ 正确写法:先检测,再调用,有降级
以下是一个健壮、可复用的 dbExists 检测函数,兼顾兼容性与语义清晰:
/**
* 检查指定名称的 IndexedDB 数据库是否存在(支持现代 & 降级方案)
* @param {string} dbName - 数据库名
* @returns {Promise<boolean>} 解析为 true 表示数据库已存在
*/
async function dbExists(dbName) {
// 1. 确保环境支持 indexedDB
if (!window.indexedDB) {
console.warn('IndexedDB not supported in this browser.');
return false;
}
// 2. 优先尝试使用标准 databases() API(现代浏览器)
if (typeof window.indexedDB.databases === 'function') {
try {
const dbs = await window.indexedDB.databases();
return dbs.some(db => db.name === dbName);
} catch (err) {
console.warn('Failed to list databases via .databases():', err);
// 继续降级处理
}
}
// 3. 【降级方案】尝试打开数据库并监听 onupgradeneeded —— 若触发,说明数据库不存在(或版本过低)
// 注意:此处仅检测存在性,不实际创建/升级,因此 version 设为 1,且不执行任何 upgrade logic
return new Promise(resolve => {
const req = window.indexedDB.open(dbName, 1);
let didOpen = false;
req.onsuccess = () => {
didOpen = true;
req.result.close(); // 立即关闭,避免资源占用
resolve(true);
};
req.onupgradeneeded = () => {
// onupgradeneeded 被触发 → 数据库不存在(或需升级),但我们只关心“存在”
// 若从未存在过,则此事件必触发;若存在且版本 ≥1,则不会触发
resolve(false);
};
req.onerror = () => {
// 打开失败(如权限问题)→ 保守返回 false
if (!didOpen) resolve(false);
};
// 防止长时间挂起(超时兜底)
setTimeout(() => {
if (!didOpen) {
req.result?.close?.();
resolve(false);
}
}, 2000);
});
}
// 使用示例
dbExists('myAppDB').then(exists => {
console.log(`Database 'myAppDB' exists: ${exists}`);
if (!exists) {
console.log('You may need to initialize it first.');
}
}).catch(console.error);⚠️ 关键注意事项
-
不要依赖
.catch()捕获databases()的undefined错误:该错误是同步抛出,必须用typeof ... === 'function'或try/catch包裹整个调用表达式。 -
Safari 用户注意:
databases()永远不可用,务必实现降级逻辑(如上所示的open()+onupgradeneeded检测)。 -
性能提示:
databases()是轻量级 API,但降级方案涉及一次indexedDB.open(),会产生微小开销;生产环境建议缓存结果或结合业务生命周期管理。 - 安全性边界:该方法仅返回当前 Origin 下的数据库列表,受同源策略严格保护,无法跨域探测。
✅ 总结
解决 Uncaught (in promise) TypeError: window.indexedDB.databases is not a function 的核心在于:区分“Promise 内部错误”与“API 本身不可用”两类问题。前者用 .catch(),后者必须前置检测。将兼容性判断、现代 API 尝试、优雅降级三者结合,才能写出真正鲁棒的 IndexedDB 工具函数。

















