uni-app文件上传踩坑记:图片处理和上传全攻略 0 次阅读

在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题。本文总结了一些常见问题和解决方案,希望能帮助大家更好地处理文件上传相关的需求。

1. 图片选择问题

1.1 图片选择数量限制

问题描述:
选择图片时没有限制数量,导致用户可能选择太多图片。

解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 限制选择数量和大小
async chooseImages() {
try {
const res = await uni.chooseImage({
count: 9, // 最多选择9张
sizeType: ['original', 'compressed'], // 原图和压缩图都可以
sourceType: ['album', 'camera'] // 相册和相机都可以
})

// 检查文件大小
const maxSize = 5 * 1024 * 1024 // 5MB
const overSizeFiles = res.tempFiles.filter(file => file.size > maxSize)
if (overSizeFiles.length > 0) {
uni.showToast({
title: '图片大小不能超过5MB',
icon: 'none'
})
return
}

this.handleUpload(res.tempFilePaths)
} catch (e) {
console.error('选择图片失败:', e)
}
}

1.2 图片格式限制

问题描述:
用户上传了不支持的图片格式。

解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 检查图片格式
function checkImageType(filePath) {
const allowTypes = ['jpg', 'jpeg', 'png', 'gif']
const extension = filePath.split('.').pop().toLowerCase()

if (!allowTypes.includes(extension)) {
uni.showToast({
title: '只支持jpg、png、gif格式',
icon: 'none'
})
return false
}
return true
}

2. 图片压缩问题

2.1 上传前压缩

问题描述:
图片太大导致上传慢,浪费流量。

解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 压缩图片
async compressImage(tempFilePath) {
try {
const res = await uni.compressImage({
src: tempFilePath,
quality: 80 // 压缩质量0-100
})
return res.tempFilePath
} catch (e) {
console.error('压缩失败:', e)
return tempFilePath // 压缩失败返回原图
}
}

// 使用示例
async handleUpload(tempFilePaths) {
const compressedPaths = []
for (let path of tempFilePaths) {
const compressed = await this.compressImage(path)
compressedPaths.push(compressed)
}
this.uploadFiles(compressedPaths)
}

2.2 大图预览优化

问题描述:
直接预览原图占用内存大,可能导致卡顿。

解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 预览时使用缩略图,点击查看原图
const imageList = {
original: [], // 原图
thumbnail: [] // 缩略图
}

// 预览图片
function previewImage(index) {
uni.previewImage({
urls: imageList.original,
current: index,
// 显示加载提示
showmenu: true,
success: () => {
console.log('预览成功')
},
fail: () => {
uni.showToast({
title: '预览失败',
icon: 'none'
})
}
})
}

3. 上传进度问题

3.1 进度显示不准

问题描述:
上传进度显示不准确,影响用户体验。

解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 更精确的进度显示
function uploadFile(filePath) {
return new Promise((resolve, reject) => {
const uploadTask = uni.uploadFile({
url: 'your-upload-url',
filePath: filePath,
name: 'file',
success: res => resolve(res),
fail: err => reject(err)
})

// 监听上传进度
uploadTask.onProgressUpdate(res => {
const progress = res.progress
const speed = (res.totalBytesSent / 1024 / 1024).toFixed(2)

this.uploadInfo = {
progress: progress,
speed: speed + 'MB/s'
}

// 更新UI显示
this.$set(this.uploadProgress, filePath, progress)
})
})
}

3.2 批量上传进度

问题描述:
多文件上传时无法显示总体进度。

解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 批量上传进度管理
async uploadFiles(files) {
const total = files.length
let completed = 0

this.totalProgress = 0

const uploads = files.map(async (file, index) => {
try {
await this.uploadFile(file)
completed++
// 更新总进度
this.totalProgress = Math.floor((completed / total) * 100)
} catch (e) {
console.error(`文件${index + 1}上传失败:`, e)
}
})

await Promise.all(uploads)
}

4. 上传错误处理

4.1 断网重传

问题描述:
上传过程中断网导致上传失败。

解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 添加重试机制
async uploadWithRetry(file, maxRetries = 3) {
let retries = 0

while (retries < maxRetries) {
try {
return await this.uploadFile(file)
} catch (e) {
retries++
if (retries === maxRetries) {
throw new Error('上传失败,请检查网络后重试')
}
// 等待后重试
await new Promise(resolve => setTimeout(resolve, 1000))
}
}
}

4.2 错误提示优化

问题描述:
上传失败时提示不够友好。

解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 优化错误提示
function handleUploadError(error) {
let message = '上传失败'

// 根据错误类型显示不同提示
switch (error.code) {
case 'NETWORK_ERROR':
message = '网络异常,请检查网络设置'
break
case 'SIZE_EXCEED':
message = '文件大小超出限制'
break
case 'TYPE_ERROR':
message = '不支持的文件类型'
break
default:
message = error.message || '上传失败,请重试'
}

uni.showToast({
title: message,
icon: 'none',
duration: 2000
})
}

5. 实用技巧分享

5.1 自动重命名

1
2
3
4
5
6
7
// 生成文件名
function generateFileName(file) {
const date = new Date()
const random = Math.floor(Math.random() * 10000)
const extension = file.split('.').pop()
return `${date.getTime()}_${random}.${extension}`
}

5.2 秒传优化

1
2
3
4
5
6
7
8
9
10
11
12
13
// 检查文件是否已上传
async checkFileExists(file) {
const md5 = await this.calculateMD5(file)
try {
const res = await this.checkMD5(md5)
if (res.exists) {
return res.url
}
return false
} catch (e) {
return false
}
}

6. 最佳实践建议

  1. 上传前做好校验
  2. 合理使用压缩
  3. 添加重试机制
  4. 优化用户体验
  5. 做好错误处理

7. 总结

  1. 注意文件大小限制
  2. 处理好进度显示
  3. 优化上传体验
  4. 做好容错处理
  5. 保持代码可维护

如果觉得文章对你有帮助,欢迎点赞、评论、分享,你的支持是我继续创作的动力!

上一篇 uni-app地图定位踩坑记:地图功能和定位的那些坑
下一篇 uni-app表单验证踩坑记:这些坑我替你踩过了
感谢您的支持!
微信赞赏码 微信赞赏
支付宝赞赏码 支付宝赞赏