2025-07-28
Uniapp
0

目录

Uniapp文件上传下载工具详解
文件上传功能
文件下载功能
辅助功能
清理临时文件
获取文件扩展名
完整代码
使用示例
总结

Uniapp文件上传下载工具详解

在移动应用开发中,文件的上传和下载是常见的功能需求。本文将详细介绍一个基于Uniapp的文件上传下载工具的实现,帮助开发者快速集成文件操作功能到自己的应用中。

文件上传功能

文件上传功能通过uploadFile函数实现,它接收一个文件URL作为参数,返回一个Promise对象,便于异步处理上传结果。

javascript
/** * 上传文件到服务器 * @param {string} url - 要上传的本地文件路径 * @returns {Promise} 返回一个Promise对象,成功时解析为文件URL,失败时拒绝并返回错误 */ export const uploadFile = (url) => { return new Promise((resolve, reject) => { // 使用uni.uploadFile API上传文件 uni.uploadFile({ url: baseUrl + '/file/upload', // 拼接基础URL和上传接口路径 filePath: url, // 要上传的文件路径 name: 'file', // 后端接收的文件字段名 header: { 'medical-trial-drug': uni.getStorageSync('token') // 添加认证token到请求头 }, success: (response) => { // 上传成功回调 const res = JSON.parse(response.data) // 解析响应数据 if (res.code === 200) { resolve(res.data.url) // 上传成功,解析返回的文件URL } else { uni.$u.toast('上传失败') // 显示上传失败提示 reject(new Error('上传失败')) // 拒绝Promise } }, fail: (err) => { // 上传失败回调 reject(err) // 拒绝Promise并传递错误对象 } }) }) }

文件下载功能

文件下载功能通过downloadFile函数实现,它能够根据文件类型自动选择适当的打开方式,并提供了下载进度显示。

javascript
/** * 下载并打开文件,根据文件类型自动选择打开方式 * @param {string} url - 要下载的文件远程URL */ export const downloadFile = (url) => { console.log('文件原始远程地址:', url) const suffix = getFileExtension(url) // 获取文件后缀名 console.log('文件后缀为:', suffix) // 定义文档类型后缀数组 const docSuffix = ['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx'] // 定义图片类型后缀数组 const imgSuffix = ['jpg','jpeg','png','bmp','webp','tiff','tif','gif','svg','ai','raw','heic','heif','ico','eps','avif','jxr','hdp','xcf','psd','psb','drf','dng','xpm','pnm','ppm','pgm','pbm'] const fs = uni.getFileSystemManager() // 获取文件系统管理器实例 removeTempFile(fs) // 清理临时文件 // 创建下载任务 const downloadTask = uni.downloadFile({ url: url, // 文件的下载路径 success: (res) => { // 下载成功回调 const fileName = res.tempFilePath.split('/').pop().split('#')[0].split('?')[0] const localFilePath = `${uni.env.USER_DATA_PATH}/${fileName}` console.log('文件路径:', localFilePath) // 根据文件类型选择打开方式 if (docSuffix.includes(suffix)) { // 文档类型使用openDocument打开 uni.openDocument({ filePath: res.tempFilePath, showMenu: true, // 显示菜单,允许用户选择其他应用打开 success: (res) => { console.log('打开文档成功') } }) } else if (imgSuffix.includes(suffix)) { // 图片类型使用previewImage预览 uni.previewImage({ urls: [res.tempFilePath], showMenu: true, // 显示菜单,允许用户保存图片 success: (res) => { console.log('打开图片成功') } }) } else { // 其他类型提示不支持并尝试保存到本地 uni.$u.toast('图片不支持打开') fs.saveFile({ tempFilePath: res.tempFilePath, // 临时文件路径 filePath: localFilePath, // 要保存的本地路径 success: (res) => { uni.$u.toast('图片已保存到本地:', localFilePath) }, fail: (err) =>{ console.log('保存失败', err) }, complete: () => { console.log('保存完成') } }) } }, fail: (err) =>{ console.log('下载失败', err) }, complete:() => { console.log('下载完成') } }) // 监听下载进度变化 downloadTask.onProgressUpdate((res) => { console.log('下载进度:', res.progress) // 显示下载进度提示 uni.showLoading({ title: `下载中 ${res.progress}%`, mask: true // 添加遮罩防止用户操作 }) if (res.progress === 100) { uni.hideLoading() // 下载完成隐藏提示 } }) }

辅助功能

清理临时文件

javascript
/** * 清理缓存中的临时文件 * @param {Object} fs - 文件系统管理器实例 */ const removeTempFile = (fs) => { // 获取所有已保存的文件列表 fs.getSavedFileList({ success: (res) => { console.log('缓存中的文件为:', res.fileList) if (res.fileList.length > 0) { // 遍历并删除所有临时文件 for (let i = 0; i < res.fileList.length; i++) { fs.removeSavedFile({ filePath: res.fileList[i].filePath, // 要删除的文件路径 success: (res) => { console.log('删除成功', res) }, fail: (err) =>{ console.log('删除失败', err) }, complete: (res) => { console.log('删除文件完成', res) } }) } } }, error: (res) => { console.log('获取文件异常', res) }, complete: (res) => { console.log('获取文件完成') } }) }

获取文件扩展名

javascript
/** * 从URL中提取文件扩展名 * @param {string} url - 文件URL * @returns {string} 文件扩展名(小写) */ function getFileExtension(url) { // 使用正则匹配URL中的文件扩展名 return (url.match(/\.([^./]+)(?:[\?#]|$)/)?.[1] || '').toLowerCase() }

完整代码

javascript
// 上传文件 import { baseUrl } from '@/util/http' /** * 上传文件到服务器 * @param {string} url - 要上传的本地文件路径 * @returns {Promise} 返回一个Promise对象,成功时解析为文件URL,失败时拒绝并返回错误 */ export const uploadFile = (url) => { return new Promise((resolve, reject) => { uni.uploadFile({ url: baseUrl + '/file/upload', filePath: url, name: 'file', header: { 'medical-trial-drug': uni.getStorageSync('token') }, success: (response) => { const res = JSON.parse(response.data) if (res.code === 200) { resolve(res.data.url) } else { uni.$u.toast('上传失败') reject(new Error('上传失败')) } }, fail: (err) => { reject(err) } }) }) } /** * 下载并打开文件,根据文件类型自动选择打开方式 * @param {string} url - 要下载的文件远程URL */ export const downloadFile = (url) => { console.log('文件原始远程地址:', url) const suffix = getFileExtension(url) console.log('文件后缀为:', suffix) const docSuffix = ['doc', 'xls', 'ppt', 'pdf', 'docx', 'xlsx', 'pptx'] const imgSuffix = ['jpg','jpeg','png','bmp','webp','tiff','tif','gif','svg','ai','raw','heic','heif','ico','eps','avif','jxr','hdp','xcf','psd','psb','drf','dng','xpm','pnm','ppm','pgm','pbm'] const fs = uni.getFileSystemManager() removeTempFile(fs) const downloadTask = uni.downloadFile({ url: url, success: (res) => { const fileName = res.tempFilePath.split('/').pop().split('#')[0].split('?')[0]; const localFilePath = `${uni.env.USER_DATA_PATH}/${fileName}`; console.log('文件路径:', localFilePath); if (docSuffix.includes(suffix)) { uni.openDocument({ filePath: res.tempFilePath, showMenu: true, success: (res) => { console.log('打开文档成功'); } }); } else if (imgSuffix.includes(suffix)) { uni.previewImage({ urls: [res.tempFilePath], showMenu: true, success: (res) => { console.log('打开图片成功'); } }); } else { uni.$u.toast('图片不支持打开') fs.saveFile({ tempFilePath: res.tempFilePath, filePath: localFilePath, success: (res) => { uni.$u.toast('图片已保存到本地:', localFilePath) }, fail: (err) =>{ console.log('保存失败', err) }, complete: () => { console.log('保存完成') } }) } }, fail: (err) =>{ console.log('下载失败', err) }, complete:() => { console.log('下载完成') } }) downloadTask.onProgressUpdate((res) => { console.log('下载进度:', res.progress) uni.showLoading({ title: `下载中 ${res.progress}%`, mask: true }) if (res.progress === 100) { uni.hideLoading() } }) } /** * 清理缓存中的临时文件 * @param {Object} fs - 文件系统管理器实例 */ const removeTempFile = (fs) => { fs.getSavedFileList({ success: (res) => { console.log('缓存中的文件为:', res.fileList) if (res.fileList.length > 0) { for (let i = 0; i < res.fileList.length; i++) { fs.removeSavedFile({ filePath: res.fileList[i].filePath, success: (res) => { console.log('删除成功', res) }, fail: (err) =>{ console.log('删除失败', err) }, complete: (res) => { console.log('删除文件完成', res) } }) } } }, error: (res) => { console.log('获取文件异常', res) }, complete: (res) => { console.log('获取文件完成') } }) } /** * 从URL中提取文件扩展名 * @param {string} url - 文件URL * @returns {string} 文件扩展名(小写) */ function getFileExtension(url) { return (url.match(/\.([^./]+)(?:[\?#]|$)/)?.[1] || '').toLowerCase(); }

使用示例

html
<view> <up-upload v-if="!withdrawRecord.invoiceUrl" @afterRead="toUpload" :maxCount="1" width="250" height="150" /> <view v-else class="image-container"> <image :src="withdrawRecord.invoiceUrl" style="width: 250px;height: 150px;" /> <up-icon class="close-icon" name="close" @click="remove" /> </view> </view> <script setup> const toUpload = async(event) => { uploadFile(event.file.url).then(url => { withdrawRecord.value.invoiceUrl = url }) } </script>

总结

本文详细介绍了Uniapp中文件上传下载工具的实现,包括:

  1. 文件上传功能,支持Promise异步处理
  2. 文件下载功能,根据文件类型自动选择打开方式
  3. 下载进度显示和临时文件清理
  4. 文件扩展名提取工具函数

这个工具类可以方便地集成到各种Uniapp项目中,满足基本的文件操作需求。开发者可以根据实际项目需求进行进一步定制和扩展。