uniapp根据minio签名地址实现文件直传

目录

前言

解决办法

选择图片

md5文件名加密并获取签名地址

获取文件字节流


前言

在uniapp中我们通常上传文件使用官方的接口uni.uploadFile

但是该接口使用的是post请求,而minio直传需要为PUT请求

官方文档链接:uni.uploadFile(OBJECT) | uni-app官网 (dcloud.net.cn)

解决办法

本方案基于后端返回签名地址后,前端根据签名地址来实现minio直传

选择图片

以上传图片为例 为了方便理解此处使用了uniapp官方的选择图片API uni.chooseImage

选择图片官方文档链接:uni-app官网 (dcloud.net.cn)

		uni.chooseImage({
			count: 1, //数量
			sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
			sourceType: ['album'], //从相册选择
			success: function(res) {
				
				avatarUrl.value[0] = res.tempFilePaths[0] //返回的文件路径
				let fileName = res.tempFiles[0].name //文件名
				//包装后的上传的接口
                uploadFile({
					biz: "avatar"
				}, fileName, avatarUrl.value[0]).then(res => {
					
					console.log("上传结果", res);
					
					
				})
			}
		});

md5文件名加密并获取签名地址

md5 加密我这里使用了js-md5 使用和安装都十分简单,这里放上npm链接

npm 链接js-md5 - npm (npmjs.com)

加密核心代码如下,第一行是拆分了到文件名的后缀

第二行将加密后文件名和后缀合并

const suffix = fileName.substring(fileName.lastIndexOf("."));
const fileMd5 = md5(fileName) + suffix;

 将文件名加密后发给后端,后端返回给你签名地址。代码如下

import md5 from 'js-md5'

// 获取文件上传地址  这里简单使用promise简单封装了一下uni.request 只是一个简单的get请求
export function getFileUrl(params) {
	return request({ 
		url: "/third-server/minio/v1/policy", //这里换成你自己的获取签名的接口地址
		method: "GET",
		data: params
	})
}

export async function uploadFile(type, fileName, file) {
	// console.log("文件名", fileName);
	const suffix = fileName.substring(fileName.lastIndexOf("."));
	const fileMd5 = md5(fileName) + suffix;
	return new Promise(resolve => {
		// 获取minio对象存储签名
		getFileUrl({
			filename: fileMd5
		}).then((res) => {
			// console.log(file);
			console.log("获取签名结果", res);
			var objectName = res.data.objectName
			let fileUrl = res.data.fileUrl
			
			resolve(objectName)
		})
	})
}

获取文件字节流并上传

当我们使用uni.chooseImage选择到文件后他给我们返回的是这样一个结果

而当我们打开这个链接 图片可以正常显示

我们需要获取到这个图片的字节流

其实方法很简单 使用一个get请求就好了

注意设置好responseType 这里我返回结果如下

获取到字节流后使用PUT请求直接上传即可

url为后端返回的直传签名地址, 如果出现上传成功却不能正常显示的现象就注意你的请求头部分是否正确 
       

			uni.request({
				url: file, //uni.chooseImage返回的文件地址
				method: 'GET',
				responseType: 'arraybuffer', //此处注意不能少
				success: (res) => {
					console.log("字节流上传返回", res.data);
					let binaryData = res.data //返回的字节流
					// minio直传
					uni.request({
						url: fileUrl,//后端返回的签名地址
						data: binaryData , //上传的文件字节流
						method: 'PUT',
						header: {
							'Content-Type': 'application/octet-stream' //此处注意
						},
						success: (res) => {
							console.log("直传返回", res);
						}
					});
				}
			});

完整代码如下:

import md5 from 'js-md5'
// 获取文件上传地址
export function getFileUrl(params) {
	return request({
		url: "/third-server/minio/v1/policy",
		method: "GET",
		data: params
	})
}
// 文件上传
export async function uploadFile(type, fileName, file) {
	// console.log("文件名", fileName);
	const suffix = fileName.substring(fileName.lastIndexOf("."));
	const fileMd5 = md5(fileName) + suffix;
	return new Promise(resolve => {
		// 获取minio对象存储签名
		getFileUrl({
			filename: fileMd5
		}).then((res) => {
			// console.log(file);
			console.log("获取签名结果", res);
			var objectName = res.data.objectName
			let fileUrl = res.data.fileUrl
			// 识别文件为字节流
			uni.request({
				url: file,
				method: 'GET',
				responseType: 'arraybuffer',
				success: (res) => {
					console.log("字节流上传返回", res.data);
					let data = res.data
					// minio直传
					uni.request({
						url: fileUrl,
						data: data,
						method: 'PUT',
						header: {
							'Content-Type': 'application/octet-stream'
							// 'Authorization': `Bearer ${getToken()}`,
						},
						success: (res) => {
							console.log("直传返回", res);
						}
					});
				}
			});
			resolve(objectName)
		})
	})
}

创作不易,还请点赞支持一下

  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值