uniapp-H5端使用uni.uploadFile上传图片或图像,文件没有后缀名,导致图片上传失败的解决办法

1、先说问题吧

我最近写了一个小程序,有一个拍照上传图片的功能,用Uview的u-upload组件写的,在小程序端测试一切功能正常,但是到H5端就发现图片没法传给后端或者传过去的图片后端无法识别,报500错误

原始代码

async afterRead(event) {
				// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
				let lists = [].concat(event.file)
				let fileListLen = this[`fileList${event.name}`].length
				lists.map((item) => {
					this[`fileList${event.name}`].push({
						...item,
						status: 'uploading',
						message: '上传中'
					})
				})
				for (let i = 0; i < lists.length; i++) {
					const result = await this.uploadFilePromise(lists[i].url)
					let item = this[`fileList${event.name}`][fileListLen]
					this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
						status: 'success',
						message: '',
						url: result
					}))
					fileListLen++
				}
			},
			uploadFilePromise(url) {
				return new Promise((resolve, reject) => {
					let a = uni.uploadFile({
						url: this.baseUrl + '/common/upload',
						filePath: url,  
						name: 'file',  
						formData: {}, 
						header: {  
						  Authorization: 'Bearer ' + getToken(), 
						 'Content-Type': 'multipart/form-data' 
						},  
						success: (res) => {
							this.lastList.push(JSON.parse(res.data).fileName)
							this.files=this.lastList.join(',')
							setTimeout(() => {
								resolve(res.data.data)
							}, 1000)
						}
					});
				})
			},

后台调试发现的问题

这里看似数据上传成功了,但是

发现后端并没有给返回数据,还来了个500,正常来说此时应该请教后端大佬的,但是这个地方比较特殊,问题在于前端传过去的数据有问题,但是这个不怪我们,而是uniapp官方背大锅,h5端与其他小程序、app在这个地方的处理方式不同,上面的方法其他端通用,唯独h5不行,请看vcr

uni.uploadFile(OBJECT) | uni-app官网

问题就在这里,h5端上传前必须转为file对象上传,其他端直接filePath就ok;

2、解决办法(超级大招)

代码放下边了,具体的改动就是我上面图片画红框的地方

整体流程思路:

        1、基本上传的图片无非就是base64编码或者blob对象或者"blob:https://localhost:9090/2a68b651-7a69-48c8-9998-a9bdde15f52a"

        2、无论是上面哪种情况,直接将base64转file或者blob转file

        大多数应该是blob这种情况,下面也有示例代码,大家对照着抄就完事了

// 新增图片
			async afterRead(event) {
				// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
				let lists = [].concat(event.file)
				console.log(lists)
				let fileListLen = this[`fileList${event.name}`].length
				lists.map((item) => {
					this[`fileList${event.name}`].push({
						...item,
						status: 'uploading',
						message: '上传中'
					})
				})
				for (let i = 0; i < lists.length; i++) {
				// 将blob转为file对象的方法
				function blobToFile(blob,fileName){
					return new File([blob],fileName,{type:'image/png'})
				}
				// 获取blob对象
				fetch(lists[i].url)
					.then(response=>response.blob())
					.then(blob=>{
						// 将blob转换为file
						let fileN = blobToFile(blob,lists[i].name)
						// 上传file对象
						this.uploadFilePromise(fileN)
							.then(result=>{
								let item = this[`fileList${event.name}`][fileListLen]
								this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
									status: 'success',
									message: '',
									url: result
								}))
								fileListLen++
							})
					})	
				}
			},
			uploadFilePromise(url) {
				// console.log(fileN)
				return new Promise((resolve, reject) => {
					let a = uni.uploadFile({
						url: this.baseUrl + '/common/upload',
						file: url,  
						name: 'file',  
						formData: {}, 
						fileType:"image",
						header: {  
						  Authorization: 'Bearer ' + getToken(), 
						 // 'Content-Type': 'multipart/form-data' 
						},  
						success: (res) => {
							console.log(res)
							this.lastList.push(JSON.parse(res.data).fileName)
							this.files=this.lastList.join(',')
							console.log(this.files)
							setTimeout(() => {
								resolve(res.data.data)
							}, 500)
						}
					});
				})
			},

有个地方忘说了,就是文件后缀名丢失的问题

接两张图给大家看一下,打印的内容分别是最开始没改代码时分别在小程序端、h5端运行打印lists[i]的结果

小程序:

h5端

对比就发现后缀少了,而官方给的解决办法就是我上面说的,上传file对象,不能直接给个filePath了。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值