uni-app 报同样的代码uni.uploadFile在H5上可成功上传多张图片 在APP下只能上传最后一张图片
uni-app 报同样的代码uni.uploadFile在H5上可成功上传多张图片 在APP下只能上传最后一张图片
开发环境 | 版本号 | 项目创建方式 |
---|---|---|
Windows | win11专业版21h2 | HBuilderX |
产品分类:uniapp/App
PC开发环境操作系统:Windows
PC开发环境操作系统版本号:win11专业版21h2
HBuilderX类型:正式
HBuilderX版本号:3.96
手机系统:Android
手机系统版本号:Android 13
手机厂商:小米
手机机型:k40
页面类型:vue
vue版本:vue2
打包方式:云端
项目创建方式:HBuilderX
示例代码:
```html
<template>
<view>
<u--form labelPosition="left">
<u-button text="请选择图片" type="primary" @click="choicePic"></u-button>
<image :src='item' v-for="(item,index) in picTempPaths" :key="index"
style="width: 120rpx;height: 120rpx;padding: 5rpx;"></image>
</u--form>
<u-button style="margin-top: 50rpx;" text="提交" type="primary" @click="submit"></u-button>
</view>
</template>
<script>
export default {
data() {
return {
picTempPaths: [],
}
},
methods: {
async submit() {
let pics = this.picTempPaths.map((value, index) => {
return {
name: 'files',
uri: value
}
})
console.log("Pics.length:", pics.length);
this.uploadTask = uni.uploadFile({
url: '/todo/upLoadPic',
files: pics,
success: (res) => {
let data = JSON.parse(res.data)
console.log("后台收到数量:", data.length);
console.log('图片后台地址: ', data);
},
});
},
choicePic() {
uni.chooseImage({
count: 5,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => { //要使用箭头函数,否则访问不到this
res.tempFilePaths.forEach(item => {
this.picTempPaths.push(item)
})
},
})
},
},
}
</script>
操作步骤: 同样的代码uni.uploadFile在H5上可以成功上传多张图片,在APP下只能上传最后一张图片,查看后端接收的数据,H5发送时正常接收多张图片,app端发送时只能收到一张图片(多个图片最后的一个),用手机和夜神模拟器都一样结果
预期结果: 可以正常上传多张图片
实际结果: 在H5上可以成功上传多张图片,在APP下只能上传最后一张图片
bug描述: 同样的代码uni.uploadFile在H5上可以成功上传多张图片,在APP下只能上传最后一张图片,查看后端接收的数据,H5发送时正常接收多张图片,app端发送时只能收到一张图片(多个图片最后的一个),用手机和夜神模拟器都一样结果
已解决,前端和后端面代码都有问题1、还是因为对文档理解的不透彻 2、关键技术掌握不好
原来的前端 name 相同, 后端webapi接收参数不对:
public async Task<ActionResult> UpLoadPic(IFormFile[] files)
{
//h5端可以成功接收多个图片,app端只能接收到最后一个
}
前端代码改一下:
let pics = this.picTempPaths.map((value, index) => {
return {
name: ‘files’, //改为 name:‘files’+index
uri: value
}
})
后端代码改一下:
[HttpPost]
public async Task<ActionResult> UpLoadPic(IFormCollection formCollection)
{
FormFileCollection formFiles = (FormFileCollection)formCollection.Files;
List<string> paths = new();
try
{
for (int i = 0; i < formFiles.Count; i++)
{
var file = formFiles[i];
if (file.Length < 0) break;
string downloadUrl = configuration.GetValue<string>(“DownloadUrl”);//路径
string tennatId = this.User.FindFirstValue(“TenantId”);
string staticDir = “wwwroot/”;
string filePath = $“UpLoadImages/{tennatId}/{DateTime.Now:yyyyMM}/”;
string fileExtension = Path.GetExtension(file.FileName);// 获取文件扩展名
var fileName = file.FileName.Replace(fileExtension, “”);//获取原文件名
string newFileName = $"{fileName}{DateTime.Now:HHmmssffff}{fileExtension}"; //原文件名+时间防止文件名冲突+扩展名
if (!Directory.Exists(staticDir + filePath))
Directory.CreateDirectory(staticDir + filePath);
using (FileStream stream = System.IO.File.Create(staticDir + filePath + newFileName))
{
await file.OpenReadStream().CopyToAsync(stream);
}
string path = downloadUrl + filePath + newFileName;
paths.Add(path);
}
return Ok(paths);
}
catch (System.Exception ex)
{
return BadRequest(ex.Message);
}
}
在 uni-app
中,uni.uploadFile
用于上传文件,但在不同平台(如 H5 和 APP)上可能会遇到不同的行为。你提到在 H5 上可以成功上传多张图片,但在 APP 下只能上传最后一张图片,这通常是由于以下原因之一:
1. 异步问题
uni.uploadFile
是异步操作,如果你在循环中调用 uni.uploadFile
,可能会导致只有最后一个请求成功执行。这是因为在循环中,后续的请求可能会覆盖之前的请求。
解决方案:
使用 Promise
或 async/await
来确保每个上传操作按顺序执行。
async function uploadImages(files) {
for (let i = 0; i < files.length; i++) {
await uni.uploadFile({
url: 'https://example.com/upload',
filePath: files[i],
name: 'file',
success: (res) => {
console.log('上传成功', res);
},
fail: (err) => {
console.error('上传失败', err);
}
});
}
}
// 调用上传函数
uploadImages(fileList);
2. 文件路径问题
在 APP 平台上,文件路径可能与 H5 平台不同。确保你提供的 filePath
是正确的,并且文件确实存在。
解决方案:
检查 filePath
是否正确,并确保文件存在。
console.log('文件路径:', filePath);
3. 并发限制
某些平台可能对并发上传请求有限制,导致只有最后一个请求成功。
解决方案:
限制并发上传请求的数量,或者使用 Promise.all
来管理多个上传请求。
function uploadImage(file) {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: 'https://example.com/upload',
filePath: file,
name: 'file',
success: (res) => {
resolve(res);
},
fail: (err) => {
reject(err);
}
});
});
}
async function uploadImages(files) {
const uploadPromises = files.map(file => uploadImage(file));
await Promise.all(uploadPromises);
}
// 调用上传函数
uploadImages(fileList);
4. 平台差异
不同平台(如 H5 和 APP)可能会有不同的实现细节,导致行为不一致。
解决方案:
检查 uni-app
的官方文档,了解不同平台上的差异,并根据需要进行适配。
5. 调试
使用 console.log
或调试工具来检查每个上传请求的状态,确保每个请求都正确执行。
uni.uploadFile({
url: 'https://example.com/upload',
filePath: filePath,
name: 'file',
success: (res) => {
console.log('上传成功', res);
},
fail: (err) => {
console.error('上传失败', err);
}
});