如何在Apache Cordova安卓应用中下载SQLite备份生成的JSON文件
我搭建了一套*「备份系统」*,可将SQLite数据库的所有表记录导出为.json格式文件。该下载功能在浏览器中运行完全正常,但在安卓端无法生效。
#1 - 打开数据库连接
#2 - 处理错误
#3 - 对所有数据库表执行SELECT查询
#4 - 生成备份(将记录转为.json格式,创建数据库备份文件)
#5 - 通用工具函数(convertResults)

原有实现代码:
// 备份功能实现代码 $(document).ready(function() { console.log("应用启动") var db; // → #1 打开数据库连接 db = window.openDatabase("DB_registry", "1.0", "DB_registry", 10485760) // → #2 错误处理 // 通用错误处理器 function dbError(e) { console.log("SQL执行错误"); console.dir(e); } // → #3 对所有数据库表执行SELECT查询 function backup(table) { var def = new $.Deferred(); db.readTransaction(function(tx) { tx.executeSql("select * from "+table, [], function(tx,results) { console.log('↓ SQL结果集 ↓') console.log(results) var data = convertResults(results) def.resolve(data) }); }, dbError); return def; } // → #4 生成备份文件 $(document).on("click", "#doBackupBtn", function(e) { e.preventDefault(); console.log("开始备份流程"); $.when( backup("tb_registry"), backup("tb_courses"), ).then(function(tb_registry, tb_courses) { // 转换为JSON格式 var data = {tb_registry:tb_registry, tb_courses:tb_courses} var serializedData = JSON.stringify(data, null, 2) $('#showRegistry').text(serializedData) var obj = data var data = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(obj)); // 创建备份文件下载链接 var a = document.createElement('a'); a.href = 'data:' + data; a.download = 'data.json'; a.innerHTML = '下载JSON文件'; var container = document.getElementById('container'); container.appendChild(a); }) }) // 通用工具函数 function convertResults(resultset) { var results = [] for(var i=0,len=resultset.rows.length;i<len;i++) { var row = resultset.rows.item(i) var result = {} for(var key in row) { result[key] = row[key]; } results.push(result); } return results; } })
问题原因
安卓端浏览器、应用内置WebView对data: URI搭配download属性的支持度极低,是当前功能失效的核心原因。
解决方案
将data: URI方案替换为Blob+URL.createObjectURL实现,同时主动触发点击事件,兼容安卓端下载逻辑。以下是修改后的核心代码(仅替换#4生成备份文件部分即可):
$(document).on("click", "#doBackupBtn", function(e) { e.preventDefault(); console.log("开始备份流程"); $.when( backup("tb_registry"), backup("tb_courses"), ).then(function(tb_registry, tb_courses) { var data = {tb_registry:tb_registry, tb_courses:tb_courses} var serializedData = JSON.stringify(data, null, 2) $('#showRegistry').text(serializedData) // 替换原有data URI方案为Blob方案 const blob = new Blob([serializedData], { type: 'application/json' }); const fileUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = fileUrl; a.download = 'data.json'; // 兼容安卓端触发逻辑 document.body.appendChild(a); a.click(); document.body.removeChild(a); // 释放Blob资源 setTimeout(() => URL.revokeObjectURL(fileUrl), 100); }) })
场景适配
- 纯网页场景:上述修改可兼容绝大多数安卓现代浏览器,下载的文件会自动存入系统下载文件夹。
- 混合App(WebView内嵌)场景:需要原生端额外做两项配置:
- 申请存储读写权限
- 给WebView设置下载监听器,监听到下载请求时调用系统下载管理器写入公共下载目录
内容的提问来源于stack exchange,提问作者Comentarista
相关产品推荐
相关产品推荐

