阿里云 OSS 上传「PUT 方式」

预计阅读时间: 4 分钟

🍉 场景需求

  最初上传文件是借助后台 API 来实现文件的存储,相对现在主流的 OSS 直传来说,还是比较繁琐的。之前介绍的文件上传是基于 OSS 直传的 POST 方式实现的,需要借助 FormData 来实现文件的上传,相关代码案例请参考我之前写的文章 iView 文件上传「OSS 直传」

  此次是借助阿里云提供的 ali-oss 来实现文件上传,此方法还支持大文件大断点续传,如有需要请参考 OSS 云存储官方提供的文档 APIOSSPUT 上传方式支持异步上传和同步上传,上传成功后直接返回上传文件在阿里云云存储上的绝对路径;之前的 POST 上传方式是将文件对象转换成 FormData 对象来上传的,其返回的是上传文件的相对路径,若想获取文件在云存储上的绝对路径,还需要自己进行手动拼接,相比较 PUT 上传方式来说比较麻烦,而且还容易出错。

🛵 前期处理

  首先要根据自己的实际情况来选择符合自己的 OSS 文件上传方式。此次我主要就 OSSPUT 文件上传方式做介绍。   先登录阿里云 OSS 云存储的管理后台,进入自己索要配置的 bucket 类型,然后查找配置跨域资源共享(CORS)规则 ,来对该 bucket 的跨域资源共享规则按照官方文档给的要求来进行相应的设置。

图例:

文件上传

注:

  • 此页面为配置跨域规则的页面,请确认已勾选 PUT**请求方式。
  • 若没勾选此方式,当采用 PUT 方式上传文件时,控制台会报请求跨域错误。

🌰 代码案例

  • 安装所需依赖
安装插件
1/* 时间处理工具 */
2import dayjs from "dayjs";
3/* 阿里云OSS文件直传工具 */
4import OSS from "ali-oss";
5/* 基于VUE的前端UI框架 */
6import { ElMessage } from "element-plus";

注意:

  • dayjs 在后续处理文件路径和文件重命名时需用到,若无需文件重命名则不用安装;
  • element-plus 为基于 Vue3ElementUI 升级版,此处主要用于文件上传时候相关校验的提示;
  • 文件重命名
文件重命名
1const fileRename = (file, rootPath = "", fileType = [], size = 0) => {
2	/* 判断传过来的值是否为file对象 */
3	if (!(file instanceof Object)) return null;
4	// 文件大小限制
5	if (size && file.size >= size * 1024 * 1024) {
6		ElMessage.warning(`上传的文件大小不能超过 ${size}M,请重新上传!`);
7		return null;
8	}
9	// 将文件名字做英文字符小写处理,为了方便判断上传文件的格式
10	let fileName = file.name.toLowerCase(),
11		dotIndex = fileName.lastIndexOf("."),
12		// 获取文件后缀名
13		fileSuffix = fileName.substr(dotIndex);
14	// 传过来的用于判断文件类型的数组,拼接成字符串
15	let fileTypeString = fileType.join(".");
16	// 文件类型限制
17	if (fileTypeString && !fileTypeString.includes(fileSuffix)) {
18		ElMessage.error("上传文件类型有误,请重新上传!");
19		return null;
20	}
21	/**
22	 * 文件路径处理
23	 * 基于dayjs来分配文件路径和对文件进行重命名
24	 *  */
25	let filePath = dayjs().format("YYYY_MM/DD_HHmmss_SSS");
26	// 返回文件在OSS上的相对文件路径
27	return rootPath + filePath + fileSuffix;
28};

文件重命名参数介绍:

  • file:文件对象;

  • rootPath:文件根路径即在 OSS 存储的根目录;

  • fileType:要校验的文件类型格式;

  • size:上传文件的大小限制。

  • OSS 文件上传

文件上传
1/**
2 * @module 文件上传
3 * @param {Object} file - 文件对象
4 * @param {String} rootPath - 文件根路径
5 * @param {Array} fileType - 文件类型
6 * @param {Number} size - 文件大小
7 * @returns {String} - 上传文件地址
8 **/
9const OSSUpload = async (file, rootPath, fileType, size) => {
10	// 调用fileRename生成的文件相对路径格式:xxxx.png,必须带后缀名,否则无法读取上传后的文件
11	let fileName = fileRename(file, rootPath, fileType, size);
12	if (!fileName) return null;
13	// *配置client-OSS
14	let client = new OSS({
15		accessKeyId: "your access key" /* 通过阿里云控制台创建的access key */,
16		accessKeySecret: "your access secret" /* 通过阿里云控制台创建的access secret */,
17		region: "oss-cn-beijing" /* bucket 所在的区域 */,
18		stsToken: "" /* 鉴权,sts方式需要使用,若不需要请删除或注释掉 */,
19		bucket: "your bucket name" /* 通过控制台创建的bucket,【OSS文件前缀】 */
20	});
21
22	try {
23		/**
24		 * OSS的put直传
25		 * fileName:文件名【带后缀名】
26		 * file:文件对象
27		 *  */
28		// File 对象
29		let { res, url } = await client.put(fileName, file);
30		// Blob 对象
31		// let { res, url } = await client.put(fileName, new Blob(file));
32		// OSS Buffer 对象
33		// let { res, url } = await client.put(fileName, new OSS.Buffer(file));
34
35		if (res.status == 200) {
36			ElMessage.success("上传成功");
37			return url;
38		}
39		ElMessage.error("上传失败");
40		return null;
41	} catch (e) {
42		ElMessage.error("文件上传失败");
43		return null;
44	}
45};
🚀
  • 多行注释处请留心配置,否则会报错。OSS.JS 附件已上传,下载后配置好 OSS 相关参数就可直接使用。
  • OSSPUT 上传方式第二参数即 file,支持 File 对象Blob 数据 以及 OSS Buffer 等格式。
  • OSS 直传使用
OSS 直传
1// 导入封装的OSS插件
2import oss from "./oss.js";
3
4/**
5 * @param {Object} file - 文件对象
6 * @param {String} rootPath - 文件根路径(默认为空、例:“filepath/”)
7 * @param {Array} fileType - 文件类型限制(默认 [] 不限制,例:['.png','.jpeg'])
8 * @param {Number} size - 文件大小限制(单位:兆、默认 0 不限制、例:1)
9 **/
10//获取到上传文件后调用OSS直传
11// 方式一:
12oss(file, "", [], 0).then(ossUrl = >{
13	if ( !! ossUrl) {
14		// 上传成功,返回上传后的绝对路径
15	} else {
16		// 上传失败,返回null
17	}
18});
19// 方式二:不做任何限制时,参数可省略
20oss(file).then(ossUrl = >!!ossUrl && (uploadURL = ossUrl));

🔔 结语

🥇🥈🥉:前期努力搬的砖,都是为后期造轮子准备的。若对您有所帮助,请帮忙点个赞 👍!