vue项目实现STS临时授权实现上传视频到OSS
2021-05-21 本文已影响0人
FE晓伟哥
使用JavaScript签名后直传
vue安装ali-oss: npm install ali-oss --save
vue中创建相应文件
1、scr下新建utils文件夹
2、在utils文件夹中新建index.js文件,存放获取阿里stsToken方法和上传方法 getAliToken()和ossUpload()
3、在utils文件夹中新建client.js文件,配置OSS参数信息
4、组件中新建upload.vue文件
//index.js
import Client from "./client";
import { getStsInfo } from 'api' //获取后台返回sts信息
export const getAliToken = (that) => {
//获取Token
return new Promise((resolve, reject) => {
getStsInfo().then((res) => {
console.log("res :>> ", res);
if (res.stateCode === 0) {
const {
AccessKeyId,
AccessKeySecret,
bucketName,
Token,
video,
pic,
} = res;
//后台返回的存放路径
that.videoOssAddress = video;
that.imgOssAddress = pic;
// this.expiration = expiration;
that.dataObj = {
region: that.region,
bucket: bucketName,
accessKeyId: AccessKeyId,
accessKeySecret: AccessKeySecret,
stsToken: Token,
};
resolve(res);
} else {
reject(false);
}
})
.catch((err) => {
console.log(err);
});
})
};
// 上传视频 oss直传
export const ossUpload = async (option, dataObj, route, callback) => {
const client = Client(dataObj),
file = option.file;
//随机命名
const random_name =
random_string(6) +
"_" +
new Date().getTime() +
"." +
file.name.split(".").pop();
//上传失败的话 可以放开下方注释代码 试试
//client.options.endpoint.protocol = "https:";
// 分片上传文件
await client
.multipartUpload(`/${route}/${random_name}`, file, {
progress: async function (p) {
let e = {};
e.percent = p * 100;
option.onProgress(e);
},
})
.then((res) => {
console.log(res);
callback(res)
})
}
// 随机生成文件名
export const random_string = (len) => {
len = len || 8;
let chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz12345678",
maxPos = chars.length,
pwd = "";
for (let i = 0; i < len; i++) {
pwd += chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
};
//client.js
const OSS = require('ali-oss');
export default function Client(data) {
//后端提供数据
return new OSS({
region: data.region, //oss-cn-beijing
accessKeyId: data.accessKeyId,
accessKeySecret: data.accessKeySecret,
stsToken: data.stsToken,
bucket: data.bucket
})
}
//upload.vue
<template>
<div>
<el-upload
:show-file-list="false"
class="upload-demo"
action="action"
:before-upload="beforeUpload"
:http-request="handleHttpRequest"
>
<el-button size="small" type="primary">选择文件</el-button>
</el-upload>
</div>
</template>
<script>
import { getAliToken, ossUpload } from "utils";
export default {
data() {
return {
//上传oss
region: "oss-cn-beijing",
dataObj: {},
videoOssAddress: "",
imgOssAddress: "",
url: ""
}
},
methods: {
// 上传之前获取sts 虚拟授权
beforeUpload(file) {
let that = this;
return new Promise((resolve, reject) => {
// 获取sts 的 token
getAliToken(that)
.then((response) => {
if (response) {
resolve(response);
} else {
reject(response);
}
})
.catch((err) => {
console.log(err);
reject(err);
});
});
},
async handleHttpRequest(option) {
console.log("option :>> ", option);
const { type } = this;
let loading = null;
loading = this.$loading({
lock: true,
text: "上传中...",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
//上传OSS
try {
let size = (option.file.size / this.pow1024(2)).toFixed(2); //上传文件的大小 MB
if (parseFloat(size) > 300) {
this.$message.error("上传视频超过限制,请上传300MB以内的视频");
return;
}
// 上传视频 this.dataObj为new OSS实例化的参数,上传的oss路径拼接this.videoOssAddress
await ossUpload(option, this.dataObj, this.videoOssAddress, (res) => {
console.log("res :>> ", res);
const {
res: { statusCode, requestUrls },
} = res; //返回状态和 url
if (statusCode == 200) {
let url = requestUrls[0].split("?")[0];
this.$message.success("上传成功!");
loading.close();
this.url = url;
} else {
loading.close();
}
});
} catch (error) {
console.log('error :>> ', error);
loading.close();
}
},
pow1024(num) {
return Math.pow(1024, num);
},
}
}
</script>
搞定 至此上传完成!