🍉场景需求
最初上传文件是借助后台API来实现文件的存储,相对现在主流的OSS直传来说,还是比较繁琐的。之前介绍的文件上传是基于OSS直传的POST方式实现的,需要借助FormData来实现文件的上传,相关代码案例请参考我之前写的文章 iView文件上传(OSS直传)。 此次是借助阿里云提供的 ali-oss 来实现文件上传,此方法还支持大文件大断点续传,如有需要请参考OSS云存储官方提供的文档API。OSS的put上传方式支持异步上传和同步上传,上传成功后直接返回上传文件在阿里云云存储上的绝对路径;之前的POST上传方式是将文件对象转换成FormData对象来上传的,其返回的是上传文件的相对路径,若想获取文件在云存储上的绝对路径,还需要自己进行手动拼接,相比较PUT上传方式来说比较麻烦,而且还容易出错。
🛵前期处理
首先要根据自己的实际情况来选择符合自己的OSS文件上传方式。此次我主要就OSS的PUT文件上传方式做介绍。
先登录阿里云OSS云存储的管理后台,进入自己索要配置的bucket类型,然后查找配置跨域资源共享(CORS)规则, 来对该bucket的跨域资源共享规则按照官方文档给的要求来进行相应的设置。
注: 此页面为配置跨域规则的页面,请确认已勾选PUT请求方式。 若没勾选此方式,当采用PUT方式上传文件时,控制台会报请求跨域错误。
🌰代码案例
- 安装所需依赖
/* 时间处理工具 */
import dayjs from "dayjs";
/* 阿里云OSS文件直传工具 */
import OSS from "ali-oss";
/* 基于VUE的前端UI框架 */
import { ElMessage } from "element-plus";
注意:
- dayjs 在后续处理文件路径和文件重命名时需用到,若无需文件重命名则不用安装;
- element-plus 为基于Vue3的ElementUI升级版,此处主要用于文件上传时候相关校验的提示;
- 文件重命名
const fileRename = (file, rootPath = "", fileType = [], size = 0) => {
/* 判断传过来的值是否为file对象 */
if (!(file instanceof Object)) return null;
// 文件大小限制
if (size && file.size >= size * 1024 * 1024) {
ElMessage.warning(`上传的文件大小不能超过 ${size}M,请重新上传!`);
return null;
}
// 将文件名字做英文字符小写处理,为了方便判断上传文件的格式
let fileName = file.name.toLowerCase(),
dotIndex = fileName.lastIndexOf("."),
// 获取文件后缀名
fileSuffix = fileName.substr(dotIndex);
// 传过来的用于判断文件类型的数组,拼接成字符串
let fileTypeString = fileType.join(".");
// 文件类型限制
if (fileTypeString && !fileTypeString.includes(fileSuffix)) {
ElMessage.error("上传文件类型有误,请重新上传!");
return null;
}
/**
* 文件路径处理
* 基于dayjs来分配文件路径和对文件进行重命名
* */
let filePath = dayjs().format("YYYY_MM/DD_HHmmss_SSS");
// 返回文件在OSS上的相对文件路径
return rootPath + filePath + fileSuffix;
};
文件重命名参数介绍:
- file:文件对象;
- rootPath:文件根路径即在OSS存储的根目录;
- fileType:要校验的文件类型格式;
- size:上传文件的大小限制。
- OSS文件上传
/**
* @module 文件上传
* @param {Object} file - 文件对象
* @param {String} rootPath - 文件根路径
* @param {Array} fileType - 文件类型
* @param {Number} size - 文件大小
* @returns {String} - 上传文件地址
**/
const OSSUpload = async (file, rootPath, fileType, size) => {
// 调用fileRename生成的文件相对路径格式:xxxx.png,必须带后缀名,否则无法读取上传后的文件
let fileName = fileRename(file, rootPath, fileType, size);
if (!fileName) return null;
// *配置client-OSS
let client = new OSS({
accessKeyId: "your access key" /* 通过阿里云控制台创建的access key */,
accessKeySecret: "your access secret" /* 通过阿里云控制台创建的access secret */,
region: "oss-cn-beijing" /* bucket 所在的区域 */,
stsToken: "" /* 鉴权,sts方式需要使用,若不需要请删除或注释掉 */,
bucket: "your bucket name" /* 通过控制台创建的bucket,【OSS文件前缀】 */
});
try {
/**
* OSS的put直传
* fileName:文件名【带后缀名】
* file:文件对象
* */
// File 对象
let { res, url } = await client.put(fileName, file);
// Blob 对象
// let { res, url } = await client.put(fileName, new Blob(file));
// OSS Buffer 对象
// let { res, url } = await client.put(fileName, new OSS.Buffer(file));
if (res.status == 200) {
ElMessage.success("上传成功");
return url;
}
ElMessage.error("上传失败");
return null;
} catch (e) {
ElMessage.error("文件上传失败");
return null;
}
};
🚀注:多行注释处请留心配置,否则会报错。OSS.JS附件已上传,下载后配置好OSS相关参数就可直接使用。oss.js
🍅参:OSS的put上传方式第二参数即file,支持File 对象、Blob 数据以及OSS Buffer 等格式。
- OSS直传使用
// 导入封装的OSS插件
import oss from "./oss.js";
/**
* @param {Object} file - 文件对象
* @param {String} rootPath - 文件根路径(默认为空、例:“filepath/”)
* @param {Array} fileType - 文件类型限制(默认 [] 不限制,例:['.png','.jpeg'])
* @param {Number} size - 文件大小限制(单位:兆、默认 0 不限制、例:1)
**/
//获取到上传文件后调用OSS直传
// 方式一:
oss(file, "", [], 0).then(ossUrl = >{
if ( !! ossUrl) {
// 上传成功,返回上传后的绝对路径
} else {
// 上传失败,返回null
}
});
// 方式二:不做任何限制时,参数可省略
oss(file).then(ossUrl = >!!ossUrl && (uploadURL = ossUrl));
🔔结语
🥇🥈🥉:前期努力搬的砖,都是为后期造轮子准备的。若对您有所帮助,请帮忙点个赞👍!