Cordova应用升级后IndexedDB数据丢失,如何迁移旧版本数据?
Cordova Android版本升级后IndexedDB数据迁移方案
问题原因
cordova-android@^7.0.0 以 file:// 作为安全源,IndexedDB数据存储在对应file:// origin的沙箱目录中;升级到cordova-android@^9.0.0后,安全源切换为http://localhost,应用会使用新的沙箱存储目录,因此无法直接读取旧版本的数据。
迁移步骤
1. 配置应用允许访问file://源
修改项目根目录下的config.xml,添加以下配置,确保应用能加载file://协议的资源:
<!-- 允许file://路径的页面导航 --> <allow-navigation href="file://*" /> <!-- 开启WebView的文件访问权限 --> <preference name="AndroidAllowFileAccess" value="true" />
同时更新index.html中的Content-Security-Policy,将file://*加入允许列表:
<meta http-equiv="Content-Security-Policy" content="default-src 'self' http://localhost file://* 'unsafe-inline' 'unsafe-eval';">
2. 编写数据迁移脚本
在应用启动的deviceready事件中添加迁移逻辑,通过iframe桥接新旧安全源的IndexedDB:
- 创建隐藏iframe加载旧
file://源的页面,复用旧版本读取IndexedDB的代码 - 旧页面读取数据后通过
postMessage传递到主页面 - 主页面将数据写入
http://localhost对应的新IndexedDB - 迁移完成后标记状态,避免重复执行
示例代码片段:
document.addEventListener('deviceready', function() { // 检查是否已完成迁移 if (localStorage.getItem('idb_migrated')) return; // 创建隐藏iframe加载旧源页面 const iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.src = 'file:///android_asset/www/old-idb-reader.html'; document.body.appendChild(iframe); // 接收旧数据 window.addEventListener('message', function(e) { if (e.data.type === 'OLD_IDB_DATA') { const oldData = e.data.payload; // 将数据写入新IndexedDB saveToNewIDB(oldData).then(() => { localStorage.setItem('idb_migrated', '1'); document.body.removeChild(iframe); alert('数据迁移完成,请重启应用'); }).catch(err => { console.error('迁移失败:', err); alert('数据迁移失败,请重试'); }); } }); }); // old-idb-reader.html中的代码 window.addEventListener('load', function() { // 复用旧版本读取IndexedDB的逻辑 readOldIDB().then(data => { window.parent.postMessage({ type: 'OLD_IDB_DATA', payload: data }, '*'); }); });
3. 验证与清理
- 测试升级流程,确认旧数据完整迁移到新存储中
- 迁移完成后,移除
config.xml和index.html中关于file://的额外配置,降低安全风险 - 可选:通过cordova-file-plugin定位并删除旧
file://源的IndexedDB目录(路径为/data/data/[你的包名]/app_webview/IndexedDB/file__0.indexeddb.leveldb)
注意事项
- 保留旧版本IndexedDB的操作逻辑,确保能正确读取旧数据
- 大量数据建议分批次迁移,避免内存溢出
- 迁移过程中提示用户不要关闭应用,防止数据中断
内容的提问来源于stack exchange,提问作者klaudiusnaban
相关产品推荐
相关产品推荐

