vue使用el-upload上传到阿里云oss
前言
项目中要实现上传到阿里云oss功能,为了降低服务器压力,使用STS方式进行上传 1.后端返回AccessKey ID,AccessKey Secret,stsToekn。 2.前端调用接口获取秘钥等信息进行上传官方文档
后端地址:https://help.aliyun.com/document_detail/32007.html
前端地址:https://help.aliyun.com/document_detail/64041.html
一、后端JAVA代码
1.引入依赖
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.25</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-sts -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-sts</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.8.0</version>
</dependency>
2.具体实现
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
/**
* @author Superlu
* @version 1.0.0
* @ClassName StsServiceSample
* @Description TODO
* @createTime 2021/12/13 13:57
*/
public class StsServiceSample {
public static AssumeRoleResponse getRoleRequest(String userId,String path){
// STS接入地址,例如sts.cn-hangzhou.aliyuncs.com。
String endpoint = "###############";
// 填写步骤1生成的访问密钥AccessKey ID和AccessKey Secret。
String AccessKeyId = "####################";
String accessKeySecret = "#######################";
// 填写步骤3获取的角色ARN。
String roleArn = "#########################";
// 自定义角色会话名称,用来区分不同的令牌,例如可填写为SessionTest。
String roleSessionName = userId;
// 以下Policy用于限制仅允许使用临时访问凭证向目标存储空间examplebucket上传文件。
// 临时访问凭证最后获得的权限是步骤4设置的角色权限和该Policy设置权限的交集,即仅允许将文件上传至目标存储空间examplebucket下的exampledir目录。
String policy = "{\n" +
" \"Version\": \"1\", \n" +
" \"Statement\": [\n" +
" {\n" +
" \"Action\": [\n" +
" \"oss:PutObject\"\n" +
" ], \n" +
" \"Resource\": [\n" +
" \"acs:oss:*:*:########桶##########/"+path+"/*\" \n" +
" ], \n" +
" \"Effect\": \"Allow\"\n" +
" }\n" +
" ]\n" +
"}";
AssumeRoleResponse response=new AssumeRoleResponse();
try {
// regionId表示RAM的地域ID。以华东1(杭州)地域为例,regionID填写为cn-hangzhou。也可以保留默认值,默认值为空字符串("")。
String regionId = "###############";
// // 添加endpoint。
// DefaultProfile.addEndpoint(regionId, "Sts", endpoint);
// 构造default profile。
IClientProfile profile = DefaultProfile.getProfile(regionId, AccessKeyId, accessKeySecret);
// 构造client。
DefaultAcsClient client = new DefaultAcsClient(profile);
final AssumeRoleRequest request = new AssumeRoleRequest();
request.setSysMethod(MethodType.POST);
request.setRoleArn(roleArn);
request.setRoleSessionName(roleSessionName);
request.setPolicy(policy); // 如果policy为空,则用户将获得该角色下所有权限。
request.setDurationSeconds(3600L); // 设置临时访问凭证的有效时间为3600秒。
response = client.getAcsResponse(request);
System.out.println("Expiration: " + response.getCredentials().getExpiration());
System.out.println("Access Key Id: " + response.getCredentials().getAccessKeyId());
System.out.println("Access Key Secret: " + response.getCredentials().getAccessKeySecret());
System.out.println("Security Token: " + response.getCredentials().getSecurityToken());
System.out.println("RequestId: " + response.getRequestId());
} catch (ClientException e) {
System.out.println("Failed:");
System.out.println("Error code: " + e.getErrCode());
System.out.println("Error message: " + e.getErrMsg());
System.out.println("RequestId: " + e.getRequestId());
}
return response;
}
}
二、前端调用
1.引入库
npm install ali-oss
2.工具类oss.js
import {ElMessage} from "element-plus";
import OSS from 'ali-oss'
import { uuid } from 'vue-uuid';
// 上传
export const uploadFile = (data, option) => {
let client = new OSS({
// yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
region: data.region,
secure: true,//*这句话很重要!!!!!!!!!
endpoint: data.endpoint,//这句话更重要,不设置为报错。STS接入地址,例如sts.cn-hangzhou.aliyuncs.com。
// 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
accessKeyId: data.accessKeyId,
accessKeySecret: data.accessKeySecret,
// 从STS服务获取的安全令牌(SecurityToken)。
stsToken: data.stsToken,
refreshSTSToken: async () => {
// 向您搭建的STS服务获取临时访问凭证。
const info = await fetch('your_sts_server');
return {
accessKeyId: info.accessKeyId,
accessKeySecret: info.accessKeySecret,
stsToken: info.stsToken
}
},
// 刷新临时访问凭证的时间间隔,单位为毫秒。
refreshSTSTokenInterval: 300000,
// 填写Bucket名称。
bucket: data.bucket
});
let file=option.file
let objectKey = uuid.v1()+ '_' + file.name;
return new Promise(async (resolve, reject) => {
await client.multipartUpload(data.path + "/" + objectKey, file,
{
progress: async function (p) {
let e = {};
e.percent = p * 100;
option.onProgress(e)
}
}).then(result => {
resolve({
code : result.res.statusCode,
name : result.name,
msg : "ok"
});
}).catch(err => {
console.error('上传出错了',err);
ElMessage.error('上传出错了');
reject({code : -1 , url : "", objectKey : "", msg : "上传出错了"});
});
})
};
3.页面使用
- auto-upload为取消自动上传
- httpRequest手动上传方法
<el-upload
action=""
ref="upload"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
multiple
:limit="3"
:on-exceed="handleExceed"
:file-list="fileLists"
:auto-upload="false"
:http-request="httpRequest"
>
<el-button type="primary">Click to upload</el-button>
<template #tip>
<div class="el-upload__tip">
jpg/png files with a size less than 500kb
</div>
</template>
</el-upload>
<el-button type="primary" @click="handleUploadSubmit">upload</el-button>
实现方法
handleUploadSubmit() {
this.$refs['upload'].submit();
}
httpRequest(){
//调用服务端接口
createUploadStsToken(this.folderId).then(async res => {
//上传到oss
uploadFile(res.data, option).then(result => {
//此处为上传成功后的返回自己的业务
})
})}