H5 WebView 文件下载到手机中(仅安卓与 iOS)
2025年11月18日 15:04
H5 WebView 文件下载(仅安卓与 iOS)
原理
- 使用 H5+ 原生接口
plus.downloader.createDownload将文件下载到本地;下载完成后通过plus.runtime.openFile打开。 - 不同平台保存路径不同:
- Android:保存到系统公共
Download目录(需要存储权限)。 - iOS:保存到应用沙箱
_doc持久目录(无需额外权限)。
- Android:保存到系统公共
使用方法(代码)
- 页面按钮“原生下载PDF”触发函数:
src/views/w-success.vue:323。 - 关键实现(节选):
// src/views/w-success.vue:323-388
const downloadByPlus = async () => {
const p = (window as any).plus;
if (!p) { alert("当前不在App环境"); return; }
if (isDownloading.value) return;
isDownloading.value = true;
downloadStatus.value = "原生下载中...";
try {
const fileOnly = getFileName(downloadUrl);
const isAndroid = p.os && p.os.name === "Android";
const isiOS = p.os && p.os.name === "iOS";
const filename = isAndroid
? `file:///storage/emulated/0/Download/${fileOnly}`
: isiOS
? `_doc/${fileOnly}`
: `_downloads/${fileOnly}`;
const startDownload = () =>
p.downloader.createDownload(
downloadUrl,
{ filename },
(d: any, status: number) => {
isDownloading.value = false;
if (status === 200) {
let localPath = "";
try { localPath = p.io.convertLocalFileSystemURL(d.filename); } catch (err) { localPath = ""; }
downloadStatus.value = localPath ? `下载完成,路径:${localPath}` : "下载完成";
try { p.runtime.openFile(d.filename); } catch (e: any) { downloadStatus.value = `${downloadStatus.value},打开失败: ${e?.message || e}`; }
} else {
downloadStatus.value = `下载失败,状态码:${status}`;
}
}
).start();
if (isAndroid) {
try {
await new Promise((resolve, reject) => {
p.android.requestPermissions(
["android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.READ_EXTERNAL_STORAGE"],
() => resolve(null),
(err: any) => reject(err)
);
});
} catch (err: any) {
isDownloading.value = false;
downloadStatus.value = `缺少存储权限: ${err?.message || err}`;
return;
}
}
startDownload();
} catch (e: any) {
isDownloading.value = false;
downloadStatus.value = `原生下载失败: ${e?.message || e}`;
}
};
保存路径
- Android:
/storage/emulated/0/Download/<文件名>(绝对路径显示为file:///storage/emulated/0/Download/<文件名>)。 - iOS:
_doc/<文件名>(绝对路径通过plus.io.convertLocalFileSystemURL转换后显示为file:///.../Documents/<文件名>等沙箱路径)。
平台要求
- Android:需要申请
WRITE_EXTERNAL_STORAGE、READ_EXTERNAL_STORAGE权限;代码中已请求(src/views/w-success.vue:356-371)。 - iOS:若下载地址为
http://,需在原生打包的 ATS 配置中允许该域名的非 HTTPS 访问;文件仅可写入应用沙箱。