鸿蒙 uni-app x 云存储上传与临时链接获取实战
适用场景与兼容性在鸿蒙端使用 uni-app x 开发应用时,头像、商品图片、视频和文档附件都需要有存储位置。原文给出的方案是直接使用 uniCloud 云存储,避免自建文件服务器;其中 uploadFile、chooseAndUploadFile、getTempFileURL 三个核心 API 在鸿蒙 4.61 全部支持。需要特别留意版本差异:4.18 之前 uni-app-x 在 app 端仅支持选择图片,type 只能设为 image;4.18 及之后的版本才支持图片和视频,type 可设为 image 或 video。
三个 API 的职责划分
uploadFile 用于把本地文件上传到云存储,核心参数是 filePath、cloudPath 和 onUploadProgress,成功后可拿到 fileID。chooseAndUploadFile 把选择文件和上传合并,支持 type、sourceType、count、sizeType、maxDuration、camera 等配置;onChooseFile 在选完文件后回调,onUploadProgress 返回上传进度,结果中的 tempFiles 可继续取 name、path、cloudPath、url 等信息。getTempFileURL 则根据 fileID 换取临时访问链接,入参是 fileList,返回结果的 fileList 中每项包含 fileID 和 tempFileURL。
上传本地文件与进度处理
上传前通常先用时间戳和扩展名生成云端唯一路径 cloudPath,再调用 uploadFile。原文示例在上传期间用 showLoading 提示,并通过 progress.loaded 与 progress.total 计算百分比;成功后拿 res.fileID,失败后在 catch 中隐藏 loading 并提示上传失败。
const uploadLocalFile = (filePath: string) => {
const timestamp = Date.now()
const ext = filePath.split('.').pop() || 'jpg'
const cloudPath = 'uploads/' + timestamp + '.' + ext
uni.showLoading({ title: '上传中...' })
uniCloud.uploadFile({
filePath: filePath,
cloudPath: cloudPath,
onUploadProgress: (progress) => {
const percent = Math.floor((progress.loaded / progress.total) * 100)
console.log('上传进度:', percent + '%')
}
}).then((res) => {
uni.hideLoading()
console.log('上传成功,fileID:', res.fileID)
uni.showToast({ title: '上传成功', icon: 'success' })
}).catch((err) => {
uni.hideLoading()
console.error('上传失败:', err)
uni.showToast({ title: '上传失败', icon: 'none' })
})
}
选择图片、视频并上传
如果希望用户先选择再自动上传,可使用 chooseAndUploadFile。图片场景可设置 type 为 image,sourceType 为 album 和 camera,count 为 1,sizeType 为 compressed;视频场景可设置 type 为 video,sourceType 为 album 和 camera,maxDuration 为 60,camera 为 back。注意视频选择要建立在 4.18 及之后版本的兼容性前提上。选择完成后,res.tempFiles 可读取 name、cloudPath、url 等结果。
uniCloud.chooseAndUploadFile({
type: 'image',
sourceType: ['album', 'camera'],
count: 1,
sizeType: ['compressed'],
onChooseFile: (res) => {
console.log('选择的文件:', res.tempFiles.name)
},
onUploadProgress: (progress) => {
const percent = Math.floor((progress.loaded / progress.total) * 100)
console.log('上传进度:', percent + '%')
}
}).then((res) => {
const file = res.tempFiles
console.log('上传成功,fileID:', file.cloudPath)
console.log('访问链接:', file.url)
uni.showToast({ title: '上传成功', icon: 'success' })
}).catch((err) => {
console.error('失败:', err)
uni.showToast({ title: '上传失败', icon: 'none' })
})
批量上传与临时链接获取
批量上传图片时,原文使用 type 为 image、sourceType 为 album、count 为 9、sizeType 为 compressed;进度回调中的 progress.index 可用于判断当前是第几张。上传结束后遍历 res.tempFiles 即可拿到每张图片的 url。获取临时链接时,单文件和批量都走 getTempFileURL,只需传入 fileList,返回后遍历 res.fileList,其中 item.fileID 对应原文件,item.tempFileURL 就是临时访问地址。
uniCloud.getTempFileURL({
fileList: ['cloud://xxx/images/avatar.jpg']
}).then((res) => {
res.fileList.forEach((item) => {
console.log('fileID:', item.fileID)
console.log('临时链接:', item.tempFileURL)
})
}).catch((err) => {
console.error('获取链接失败:', err)
})
上传后保存 fileID 到数据库
文件上传成功只是第一步,业务数据通常还要记录文件归属。原文示例先上传文件,再用 uniCloud.databaseForJQL() 获取数据库实例,向 files 集合 add 一条记录,保存 fileID、cloudPath、originalName 和 uploadTime,并给 add 参数加上 as UTSJSONObject。这样后续可以根据业务记录中的 fileID 再调用 getTempFileURL 换取临时链接。
const uploadAndSave = (filePath: string) => {
const timestamp = Date.now()
const ext = filePath.split('.').pop() || 'jpg'
const cloudPath = 'images/' + timestamp + '.' + ext
uni.showLoading({ title: '上传中...' })
uniCloud.uploadFile({
filePath: filePath,
cloudPath: cloudPath
}).then((res) => {
const db = uniCloud.databaseForJQL()
return db.collection('files').add({
fileID: res.fileID,
cloudPath: cloudPath,
originalName: filePath.split('/').pop(),
uploadTime: Date.now()
} as UTSJSONObject)
}).then((res) => {
uni.hideLoading()
console.log('上传并保存成功')
uni.showToast({ title: '上传成功', icon: 'success' })
}).catch((err) => {
uni.hideLoading()
console.error('上传或保存失败:', err)
uni.showToast({ title: '上传失败', icon: 'none' })
})
}
页面落地与排障思路
原文的完整页面使用 template 加 script setup lang="uts",维护 inputFileID、uploadProgress、uploadedFiles、tempURL 等状态,并提供上传图片、上传视频、批量上传图片、获取临时链接几个按钮。上传进度在页面中用进度条展示,上传结果与临时链接结果分块展示。排障时重点检查三类问题:一是 chooseAndUploadFile 的 type 是否与当前 uni-app-x 版本匹配,4.18 之前不要使用 video;二是上传失败是否在 catch 中正确 hideLoading 并提示;三是 getTempFileURL 前 fileID 不能为空,原文在输入为空时会直接 toast 提示请输入 fileID。
实践结论
对于鸿蒙端 uni-app x 项目,uniCloud 云存储的 uploadFile、chooseAndUploadFile、getTempFileURL 已经覆盖了上传、选择上传和临时链接换取三个关键环节。落地时把 cloudPath 唯一性、进度回调、4.18 版本兼容和 fileID 落库处理好,就可以用较少代码完成文件存储闭环;原文也明确说明,这比自己搭 OSS 简单太多。
Re: 鸿蒙 uni-app x 云存储上传与临时链接获取实战
楼主整理得挺清楚,整体看下来鸿蒙端直接走 uniCloud 云存储,确实比自建文件服务器省事。uploadFile、chooseAndUploadFile、getTempFileURL 这三个 API 的职责划分讲明白了,单文件、选择上传、批量上传和临时链接获取都能串起来。我比较关注的是版本差异那块,4.18 之前只能选图片、之后才支持视频,这个对老项目兼容很关键,做需求时得先确认基线版本。进度用 loaded 和 total 算百分比,批量时用 progress.index 判断当前张数,这两个细节很实用。想请教下,批量上传时 progress.index 是从 0 还是从 1 开始计数?另外帖子末尾 getTempFileURL 的示例好像没贴完,如果方便可以补一下返回后怎么遍历取 tempFileURL。感谢分享。Re: 鸿蒙 uni-app x 云存储上传与临时链接获取实战
感谢分享,这篇把鸿蒙端 uni-app x 的云存储上传链路讲得很清楚。印象最深的有几点:一是版本兼容性提醒很关键,4.18 之前 app 端只能选图片,4.18 及之后才支持图片和视频,这种细节如果不提前知道,做视频上传时很容易踩坑;二是 uploadFile、chooseAndUploadFile、getTempFileURL 三个 API 的职责划分很清晰,上传、选择并上传、换取临时访问地址各自负责什么,一看就明白;三是上传进度用 loaded 和 total 算百分比,以及 chooseAndUploadFile 后从 tempFiles 里取 name、path、cloudPath、url,后续展示和入库都会方便很多。批量上传时用 progress.index 判断当前第几张,结束后再遍历 tempFiles 拿每张图片的 url,这个思路也很顺。整体看,头像、商品图、视频和文档附件先走 uniCloud,确实能省掉自建文件服务器的麻烦。getTempFileURL 传入 cloud 开头的 fileID,再取 tempFileURL 作为临时访问地址,这部分也讲得很实用。感谢整理,收藏了。Re: 鸿蒙 uni-app x 云存储上传与临时链接获取实战
感谢分享,这篇把鸿蒙端 uni-app x 用 uniCloud 云存储上传的流程讲得挺清楚。头像、商品图、视频和文档附件直接走云存储,确实比自建文件服务器省事。uploadFile、chooseAndUploadFile、getTempFileURL 三个 API 的职责划分也很直观,上传、选择并上传、换临时链接各管一块。尤其版本差异提醒很关键,4.18 之前只能选图片,4.18 及之后才支持图片和视频,兼容老项目时得先确认清楚。进度处理用 loaded 和 total 算百分比,批量时用 progress.index 判断第几张,这些细节很实用。getTempFileURL 单文件和批量都传 fileList,再遍历 res.fileList 取 tempFileURL,思路也很顺。期待后续能再展开说说文档附件上传和临时链接在页面里的具体用法。
页:
[1]