uni.app上传照片并将路径转换成base64传给后端

大家好,在这里记录一篇困扰了我一天的问题:Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'. at eval (test.vue:121)   ,因为我是用uni.app

上传的照片,然后上传之后显示照片的路径为blob:http://..............但是我要的是base64格式的照片传给后端,所以我现在要将blog格式的照片转换成base64

一、使用常见的readAsDataURL()方法等

不出意外还是同样的报错:

Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'. at eval (test.vue:121)

总之,找了很多例如将blob转换成url,再将url转换成base64,或者将blob直接转换成base64等等,但都是错的,毫无变化;

二、更改修改按钮,比如改为input

看了好多大家都是使用<input type="file" >格式的上传按钮,但是我的就是如下图:

我觉得挺好的,所以这不想改,但是又没办法,就去尝试改一下,但是还是没啥变化,同样的报错、、、、

三、使用uni.app来操作

最后想到既然获取是用uni.app那么转也可以吧,然后就去搜了一下,果然有方法uni.getImageInfo()

果然可以,“解铃人还须系铃人”!

总结

全部代码:

	PutPhoto: function() {
							uni.chooseImage({
								count: 1, //图片张数,默认9
								sizeType: ['compressed'], //original 原图,compressed 压缩图,
								sourceType: ['album'], //album 从相册选图,camera 使用相机,
								success: (res) => { //成功返回的函数
								// console.log('图片路径为:', res.tempFilePaths[0]) //当前选中的图片
								// var imageSrc = res.tempFilePaths[0] //将图片的地址赋值给imageSrc
								// 转base64
									uni.getImageInfo({
										src:res.tempFilePaths[0],
										success:(path)=>{
											pathToBase64(path.path).then(base64=>{
												console.log("这是转之后的",base64);
												var imageBase64=base64;
												uni.request({ //上传图片
													url: "xxxxxxxxxxx",//后端接口
													timeout: 10000,
													method: 'POST',
													dataType: 'json',
													data: {
														personNo:this.employeeId,
														imageBase64:imageBase64,
													},
													success: (res) => { //接口调用成功的回调函数
														console.log('uploadImage success, res is:', res)
														uni.showToast({ //消息提示框
															title: '修改成功',
															icon: 'success',
															duration: 1000,
																												}),
														uni.setStorage({
															key:'image1',
															data:imageBase64
														})
														this.getAvatar(),//上传并实时刷新照片
														this.imageBase64 =imageBase64
													},
													fail: (err) => { //接口调用失败的回调函数	
														console.log('失败返回:', err);
														uni.showModal({ //消息提示框
															content: err.errMsg, //错误信息
															showCancel: false
														});
													}
												});
											})
											.catch(error=>{
												console.log(error)
											})
										}
									})
							},
							fail: (err) => { //图片接口调用失败的回调函数	
								console.log('chooseImage fail', err)
		 
						// 判断是否允许调用摄像头
										uni.getSetting({
										success: (res) => {
											let authStatus = res.authSetting['scope.album'];
											if (!authStatus) {
												uni.showModal({
													title: '授权失败',
													content: 'Hello uni-app需要从您的相册获取图片,请在设置界面打开相关权限',
													success: (res) => {
														if (res.confirm) {
															uni.openSetting()
														}
												}
											})
											}
										}
									 }) 
								}
							})
						},

最后,希望可以帮助到你们!我也会继续努力哦!(송강사랑해)

### 为什么通过 URL.createObjectURL 生成的 Blob 在使用 uni.uploadFile 上传时没有文件后缀 在使用 `URL.createObjectURL` 方法生成 Blob 对象时,该方法仅创建了一个临时的 URL 引用,用于访问内存中的数据。Blob 对象本身不包含文件名或后缀信息[^1]。因此,当通过 `uni.uploadFile` 方法上传文件时,由于未明确指定文件名和后缀,服务器可能无法正确解析文件类型。 以下是问题的具体原因分析及解决方案: --- ### 问题原因 1. **Blob 对象缺乏文件名和后缀**: - Blob 对象是一个二进制数据块,它不包含文件名或扩展名等元信息。即使通过 `URL.createObjectURL` 创建了对象 URL,该 URL 也仅仅是对 Blob 数据的一个引用,仍然缺少文件名和后缀。 - 当调用 `uni.uploadFile` 时,如果没有为文件提供明确的名称和后缀,服务器端将无法根据文件路径判断其类型[^2]。 2. **uni.uploadFile 的要求**: - `uni.uploadFile` 需要一个本地文件路径或带有文件名和后缀的文件对象作为参数。如果直接传递 Blob 对象,可能会导致上传失败或文件被识别为无效格式。 --- ### 解决方案 为了确保上传的文件能够被服务器正确解析,可以采取以下方法之一: #### 方法一:将 Blob 换为 File 对象 通过构造 `File` 对象,可以为 Blob 数据指定文件名和 MIME 类型。`File` 是基于 `Blob` 的扩展,支持额外的文件名属性。 ```javascript const blob = new Blob([audioChunks], { type: 'audio/mp3' }); const file = new File([blob], 'recording.mp3', { type: 'audio/mp3' }); // 指定文件名和 MIME 类型 ``` 然后将 `File` 对象传递给 `uni.uploadFile`: ```javascript uni.uploadFile({ url: 'https://example.com/upload', filePath: URL.createObjectURL(file), // 使用 createObjectURL 或其他方式获取路径 name: 'file', success(res) { console.log('上传成功:', res); }, fail(err) { console.error('上传失败:', err); } }); ``` 注意:某些环境中 `filePath` 不支持直接传递对象 URL。如果遇到此问题,可以尝试方法二。 --- #### 方法二:将 Blob 换为 Base64 字符串 将 Blob 数据换为 Base64 编码字符串,在服务器端解码为原始文件。这种方法适用于不支持直接上传 Blob 对象的环境。 ```javascript function blobToBase64(blob) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result); reader.onerror = reject; reader.readAsDataURL(blob); }); } blobToBase64(blob).then(base64 => { uni.uploadFile({ url: 'https://example.com/upload', filePath: base64, name: 'file', success(res) { console.log('上传成功:', res); }, fail(err) { console.error('上传失败:', err); } }); }); ``` 服务器端需要实现 Base64 解码逻辑,以还原原始文件内容[^3]。 --- #### 方法三:使用临时文件路径(特定环境) 在某些环境下(如微信小程序或 App),可以通过文件系统 API 将 Blob 数据保存为临时文件,获取其路径。 ```javascript function saveBlobAsTempFile(blob, fileName) { return new Promise((resolve, reject) => { if (typeof wx === "object" && wx.canIUse("getFileSystemManager")) { const fs = wx.getFileSystemManager(); const tempFilePath = wx.env.USER_DATA_PATH + '/' + fileName; fs.writeFile({ filePath: tempFilePath, data: blob.arrayBuffer(), encoding: 'binary', success() { resolve(tempFilePath); }, fail(error) { reject(error); } }); } else { reject(new Error("不支持的环境")); } }); } saveBlobAsTempFile(blob, 'recording.mp3').then(filePath => { uni.uploadFile({ url: 'https://example.com/upload', filePath: filePath, name: 'file', success(res) { console.log('上传成功:', res); }, fail(err) { console.error('上传失败:', err); } }); }).catch(error => { console.error('保存临时文件失败:', error); }); ``` --- ### 注意事项 - 确保服务器端能够正确处理文件上传请求,根据 MIME 类型或文件内容判断文件格式[^2]。 - 如果使用 Base64 上传,需注意数据量较大时可能导致性能问题。 - 在某些特殊环境下(如 App 或小程序),可能需要依赖平台提供的文件系统 API 来保存 Blob 数据。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值