更新记录
1.0.0(2026-07-15)
[1.0.0] - 2025-07-15
首次发布
新增
- 三端文件下载保存:统一
saveRemoteFile()API,一次调用覆盖 Android / iOS / HarmonyOS - Android MediaStore 分区存储:Android 10+ 使用
MediaStore.Downloads写入系统下载目录,无需存储权限 - Android 传统文件系统兼容:Android 9 及以下自动降级为
Environment.DIRECTORY_DOWNLOADS+WRITE_EXTERNAL_STORAGE - iOS 系统分享面板:文件保存至 Documents 目录后弹出
UIActivityViewController,用户自主选择目标 App - HarmonyOS 文件选择器:弹出系统选择器,用户自主选择保存位置
- HTTPS 自签名证书跳过:
trustAllCerts: true支持,适配内网环境(Android 使用自定义 SSLContext + hybrid.kt 混编;iOS 使用 URLSession delegate) - Content-Disposition 文件名解析:完整支持 RFC 5987 百分号编码 UTF-8 文件名(如
filename*=UTF-8''%E6%8A%A5%E5%91%8A.pdf→报告.pdf) - MIME 类型扩展名推断:根据
Content-Type自动推断文件扩展名(支持 20+ 常见类型) - 文件名自动重名序号:同名文件自动追加
(1)、(2)序号,永不覆盖已有文件 - 下载进度回调:
progress回调实时返回下载百分比(0–100) - 自定义 HTTP 请求头:
headers参数支持鉴权 Token、Cookie 等 - 磁盘空间预检:保存前检查剩余空间(至少 10MB 阈值)
- 自动打开文件:
autoOpen: true保存后调用系统默认应用打开(Android) - 请求超时配置:
timeout参数,默认 30 秒 - 后台线程下载:Android 端网络请求与文件写入均在后台线程,不阻塞 UI
- hybrid.kt 原生混编:通过 DCloud 官方 hybrid.kt 机制实现
X509TrustManager(UTS 语法无法表达 Java 协变数组形参的解决方案)
技术亮点
- **
平台兼容性
uni-app x(4.0)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| × | × | 6.0 | 15 | - | - |
其他
| 多语言 | 暗黑模式 | 宽屏模式 |
|---|---|---|
| × | √ | × |
liyq-down-save
一行代码,三端通用 · 把远程文件真正存进用户能找到的系统目录
🌟 特别适合:企业内网、私有化部署、HTTPS 自签名证书服务器的文件下载场景
saveRemoteFile 是一款基于 UTS(uni TypeScript) 的原生插件,一行调用即可完成「下载 + 保存」全流程,覆盖 Android / iOS / HarmonyOS 三端。插件内置网络请求、文件名智能解析、分区存储适配、权限兼容、进度回调等全部细节——你只管传 URL,剩下的交给它。
适用场景:内网资源拉取、私有化部署文件分发、自签名证书服务器下载、报表导出、附件下载、图片/视频保存、PDF 文档归档……
为什么选择 liyq-down-save?
如果你用过 uni.downloadFile + uni.saveFile,一定踩过这些坑:
| 你正在忍受的痛点 | liyq-down-save 的解决方案 |
|---|---|
| 下载后文件存进 App 私有目录,用户根本找不到 | 直达系统级目录——Android 存入 Downloads,用户在「文件管理」直接可见 |
| Android 10/11/12/13 分区存储适配,改到怀疑人生 | 内置 MediaStore 方案,自动适配全版本,Android 10+ 甚至免存储权限 |
| 同名文件直接覆盖,用户重要文件不翼而飞 | 自动追加序号(报告(1).pdf、报告(2).pdf),永不覆盖 |
| 内网自签名 HTTPS,下载直接报错握手失败 | trustAllCerts: true 一键放行,内网部署零障碍 |
服务端 Content-Disposition 中文文件名乱码成 %E6%8A%A5… |
自动解析 RFC 5987 百分号编码,正确还原「季度报告.pdf」 |
| 三端 API 各写一遍,行为还不一致 | 一套 API 三端通用,各自遵循原生交互习惯 |
| 大文件下载卡死 UI,进度条根本转不动 | 全程后台线程 + 实时进度回调,丝滑不卡顿 |
🌟 内网与自签名证书下载(核心特色)
这是 liyq-down-save 区别于普通下载插件的核心能力。
痛点:企业内网下载的死结
大量企业级应用部署在内网或私有云环境,出于成本和运维考虑,常使用 HTTPS 自签名证书、IP 直连、非标准域名 等方式。此时标准下载方案会直接报错:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException:
Trust anchor for certification path not found.
NSURLSession/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
uni.downloadFile 和大多数插件无法绕过这个限制——因为它们依赖系统默认的证书校验链,而自签名证书不在系统信任列表中。
方案:trustAllCerts 一键放行
liyq-down-save 在三端原生层实现了证书校验的旁路:
saveRemoteFile({
url: 'https://192.168.1.100:8443/api/export/report', // IP 直连 + 自签证书
trustAllCerts: true, // 一键放行
headers: {
'Authorization': 'Bearer internal-token' // 内网鉴权
},
saveName: '月度报表.xlsx',
success: (path) => {
console.log('内网文件已保存:', path)
}
})
三端实现机制
| 平台 | 旁路机制 | 说明 |
|---|---|---|
| Android | 自定义 SSLContext + X509TrustManager(hybrid.kt 原生混编) |
替换默认 SSLSocketFactory,信任所有证书;同时放行 HostnameVerifier 解决域名不匹配 |
| iOS | URLSessionDelegate 实现 urlSession(_:didReceive:completionHandler:) |
在证书校验回调中返回 .useCredential,接受自签名证书 |
| HarmonyOS | 系统网络栈配置 | 按鸿蒙安全模型处理 |
典型适用场景
| 场景 | 说明 |
|---|---|
| 企业内网 OA / ERP | 内部系统常用自签证书,标准方案无法下载导出的报表 |
| 私有化部署 | 客户自建服务器,证书未走公共 CA |
| 开发 / 测试环境 | 本地开发服务器使用临时自签证书 |
| IP 直连 | 无域名或使用 IP 访问,触发 Hostname 不匹配 |
| 物联网设备 | 局域网内设备提供的 HTTPS 服务 |
⚠️ 安全提醒:
trustAllCerts会跳过全部 HTTPS 证书校验,仅限可信内网环境使用。公网请求请保持默认false,避免中间人攻击风险。插件设计上此选项默认关闭,需显式开启。
平台支持
| 平台 | 支持状态 | 保存位置 | 交互方式 |
|---|---|---|---|
| Android (uni-app-x) | ✅ | 系统 Downloads 目录 | 静默保存,可选自动打开 |
| iOS (uni-app-x) | ✅ | App Documents 目录 | 系统分享面板(用户选择目标 App) |
| HarmonyOS (uni-app-x) | ✅ | 用户选择 | 系统文件选择器(用户选择保存位置) |
| Android (uni-app) | ❌ | — | 需 uni-app-x |
| iOS (uni-app) | ❌ | — | 需 uni-app-x |
| H5 / 小程序 | ❌ | — | 非原生场景 |
最低版本要求:HBuilderX 3.6.8+,uni-app-x 3.1.0+
快速开始
安装
将 liyq-down-save 插件从 DCloud 插件市场导入,或手动将 liyq-down-save/ 目录放入项目的 uni_modules/ 目录下。
三秒上手
import { saveRemoteFile } from '@/uni_modules/liyq-down-save'
saveRemoteFile({
url: 'https://example.com/report.pdf',
success: (path) => {
console.log('保存成功:', path)
},
fail: (errMsg) => {
console.error('保存失败:', errMsg)
}
})
API 文档
saveRemoteFile(options)
下载远程文件并保存到系统目录。
参数
| 属性 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
url |
string |
✅ | — | 远程文件 URL(支持 HTTP / HTTPS) |
saveName |
string |
❌ | 自动推断 | 指定保存文件名(含扩展名)。留空时从 URL / Content-Disposition 自动推断 |
autoOpen |
boolean |
❌ | false |
保存完成后是否自动用系统默认应用打开文件(仅 Android) |
trustAllCerts |
boolean |
❌ | false |
是否跳过 HTTPS 证书校验(用于内网自签名证书环境) |
headers |
Object |
❌ | {} |
自定义 HTTP 请求头(如鉴权 Token、Cookie 等) |
timeout |
number |
❌ | 30000 |
请求超时时间(毫秒) |
checkStorage |
boolean |
❌ | true |
保存前是否检查磁盘剩余空间(至少 10MB) |
success |
function |
❌ | — | 成功回调,参数为文件保存路径 string |
fail |
function |
❌ | — | 失败回调,参数为错误描述 string |
progress |
function |
❌ | — | 下载进度回调,参数 { progress: number },范围 0–100 |
文件名推断优先级
saveName(显式指定)
↓ 未指定
Content-Disposition 响应头(解析 RFC 5987 百分号编码 + UTF-8)
↓ 未包含
URL 路径最后一段
↓ 无法推断
"download" + MIME 类型推断的扩展名
使用示例
基础下载
saveRemoteFile({
url: 'https://example.com/document.pdf'
})
指定文件名 + 自动打开
saveRemoteFile({
url: 'https://example.com/report.pdf',
saveName: '2024年度报告.pdf',
autoOpen: true,
success: (path) => {
uni.showToast({ title: '已保存到 Downloads' })
}
})
带下载进度条
saveRemoteFile({
url: 'https://example.com/large-video.mp4',
saveName: '演示视频.mp4',
progress: (data) => {
console.log(`下载进度:${data.progress}%`)
uni.showLoading({ title: `${data.progress}%`, mask: true })
},
success: (path) => {
uni.hideLoading()
uni.showToast({ title: '下载完成' })
},
fail: (err) => {
uni.hideLoading()
uni.showToast({ title: err, icon: 'none' })
}
})
企业内网自签名证书 + 鉴权(👉 核心场景)
企业内网、私有化部署、IP 直连服务器的下载场景,trustAllCerts: true 一键解决证书握手失败:
saveRemoteFile({
url: 'https://internal.company.com:8443/api/export', // 自签证书 + 非标端口
trustAllCerts: true, // 跳过证书校验
headers: {
'Authorization': 'Bearer your-internal-token', // 内网鉴权
'X-Custom-Header': 'value'
},
success: (path) => {
console.log('内网文件已保存:', path)
}
})
Content-Disposition 自动文件名
服务端响应头包含 Content-Disposition: attachment; filename*=UTF-8''%E6%8A%A5%E5%91%8A.pdf 时,插件自动解码为「报告.pdf」,无需手动指定 saveName。
各平台行为说明
Android
- Android 10 (Q) 及以上:通过
MediaStore.Downloads写入系统下载目录,零权限,文件在系统「文件管理 → 下载」中直接可见 - Android 9 及以下:降级为传统文件系统方案,写入
Environment.DIRECTORY_DOWNLOADS,需声明WRITE_EXTERNAL_STORAGE(插件已在配置中限定maxSdkVersion=28) - 重名保护:检测到同名文件时自动追加序号(
报告(1).pdf、报告(2).pdf),绝不覆盖已有文件 - autoOpen:保存后通过
FileProvider+Intent调起系统默认应用直接打开
iOS
- 文件先下载至 App 的
Documents目录 - 随即弹出系统分享面板(
UIActivityViewController),由用户自主选择去向——「文件」App、微信、邮件、AirDrop…… - 完全遵循 iOS 原生交互习惯,把选择权交给用户,审核无忧
HarmonyOS
- 调起系统文件选择器,由用户主动选择保存位置
- 下载完成后写入用户选定的路径,全程透明可控
- 符合鸿蒙系统的隐私安全规范
权限配置
Android 权限
在 manifest.json → App 模块配置 中确认以下权限:
{
"permissions": [
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" android:maxSdkVersion=\"28\"/>",
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" android:maxSdkVersion=\"28\"/>"
]
}
WRITE_EXTERNAL_STORAGE设有maxSdkVersion=28,仅在 Android 9 及以下生效。Android 10+ 使用 MediaStore 无需此权限。
iOS / HarmonyOS
无需额外权限配置。
技术特性
内网 HTTPS 自签名证书旁路
详见上方 🌟 内网与自签名证书下载(核心特色) 章节。
通过 trustAllCerts: true,Android 端经 hybrid.kt 原生混编注入自定义 SSLContext + X509TrustManager + HostnameVerifier;iOS 端通过 URLSessionDelegate 接受自签名证书。完整覆盖企业内网、私有化部署、IP 直连等证书握手失败场景。
Content-Disposition 解析
完整支持 RFC 5987 标准:
filename*=UTF-8''%E6%8A%A5%E5%91%8A.pdf(百分号编码 UTF-8 文件名)filename="report.pdf"(ASCII 文件名)- 自动处理百分号解码与 UTF-8 字符串重建
MIME 类型推断
当文件名无扩展名时,根据 HTTP 响应头的 Content-Type 自动推断扩展名:
| Content-Type | 扩展名 |
|---|---|
application/pdf |
.pdf |
image/jpeg |
.jpg |
image/png |
.png |
video/mp4 |
.mp4 |
application/zip |
.zip |
application/json |
.json |
text/html |
.html |
audio/mpeg |
.mp3 |
| ... | ... |
常见问题
Q: 下载大文件时会阻塞 UI 吗?
不会。 Android 端使用后台线程执行网络请求和文件写入;iOS 端使用 URLSession 异步回调;HarmonyOS 端同样使用异步 API。全程不阻塞主线程。
Q: 支持断点续传吗?
当前版本(1.x)暂不支持断点续传。大文件下载如需断点续传能力,可在 fail 回调中记录进度,重新发起请求时通过 headers 传入 Range 头实现(需服务端支持)。
Q: trustAllCerts 安全吗?用在什么场景?
trustAllCerts 是为企业内网、私有化部署、自签名证书服务器量身定制的核心能力——这些场景下证书未走公共 CA,标准下载方案会直接握手失败。它会跳过 HTTPS 证书校验,因此仅限可信内网环境使用,公网请求请保持默认 false。插件设计上此选项默认关闭,需显式开启,避免误用。
Q: iOS 为什么不直接保存到"文件"App?
iOS 沙盒机制下,App 无法直接写入系统级目录。标准做法是先保存到 App Documents 目录,再通过系统分享面板让用户选择目标。这是 iOS 平台的系统限制,所有合规 App 均遵循此模式。
Q: 如何反馈 Bug 或申请功能?
请通过 DCloud 插件市场的「问答反馈」或直接联系作者。
版本更新
详见 changelog.md
售后与支持
- Bug 修复:购买后可终身享受 Bug 修复更新
- 使用咨询:通过 DCloud 插件市场「问答反馈」联系作者,通常 24 小时内响应
- 功能建议:欢迎提交需求,优先级高的功能将在后续版本中实现
授权许可
| 版本 | 价格 | 授权范围 |
|---|---|---|
| 标准版 | ¥69.90 | 编译产物,可在任意数量个人/企业项目中使用 |
| 源码版 | ¥199.00 | 完整源码,可自由修改、二次开发、定制功能 |
授权说明:购买即授权在任意数量项目中使用。源码版可自由修改与二次开发。禁止转售、重新分发或上传至其他插件市场。

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 0
赞赏 0
下载 12431697
赞赏 1934
赞赏
京公网安备:11010802035340号