一、準備工作
1. 開通阿里雲OSS服務,從控制檯上獲取AccessKeyId和AccessKeySecret。
2. 創建Bucket,並登錄OSS控制檯
3. 配置Bucket (很重要)
- 將allowed origins(來源)設置成 *
- 將allowed methods(允許methods)設置成 PUT, GET, POST, DELETE, HEAD
- 將allowed headers(允許headers)設置成 *
- 將expose headers(暴露headers)設置成 ETag (這裏需要換行) x-oss-request-id
可參考阿里官方文檔:https://help.aliyun.com/docum...
二、引入ali-oss
有兩種方式:
1. 在HTML文件的<head>中包含如下標籤:
<script src="http://gosspublic.alicdn.com/aliyun-oss-sdk-6.0.1.min.js"></script>
2. 項目中安裝ali-oss
npm install ali-oss --save
可參考阿里官方文檔:https://github.com/ali-sdk/al...
這裏使用第二種。
三、使用OSS
關於直傳,阿里官方給了三種方案:
- 客戶端 JavaScript 簽名後直傳;
- 客戶端申請服務端簽名,然後打包上傳;
- 客戶端申請服務端簽名,打包上傳OSS後回調服務端。
這裏使用第一種。
vue中使用步驟:
- 在src目錄中創建utils文件夾
- utils文件夾中創建Client.js
- 在組件中創建testUpload.vue文件
//Client.js
const OSS = require('ali-oss');
export default function Client(data) {
//後端提供數據
return new OSS({
region: data.region, //oss-cn-beijing-internal.aliyuncs.com
accessKeyId: data.accessKeyId,
accessKeySecret: data.accessKeySecret,
stsToken: data.stsToken,
bucket: data.bucket
})
}
//testUpload.vue
<template>
<!--在此處添加渲染的內容-->
<div>
<el-upload
class="upload-demo"
ref="upload"
drag
:before-upload="beforeUpload"
:on-success="handleSuccess"
:http-request="handleHttpRequest"
:headers="uploadHeaders"
:limit="files"
:disabled="disabled"
multiple
action=""
:file-list="fileList">
<i class="el-icon-upload"></i>
<div class="el-upload__text">將文件拖到此處,或<em>點擊上傳</em></div>
<div slot="tip" class="el-upload__tip">上傳文件大小不能超過 1G</div>
</el-upload>
</div>
</template>
<script type="text/ecmascript-6">
import Client from '../../utils/Client'
//將渲染的內容導出
export default{
props: {},
data(){
return {
region: 'oss-cn-beijing',
bucket: '',//這裏選擇OSS容器
percentage: 0,
url: '',//後臺獲取token地址
ClientObj: null,
dataObj: {},
expiration: '',
fileList: [],
files: 10,
uploadHeaders: {
authorization: '*'
},
disabled: false,
}
},
methods: {
getDate(){
const date = new Date(),
year = date.getFullYear(),
month = date.getMonth() > 9 ? date.getMonth() + 1 : `0${date.getMonth() + 1}`,
day = date.getDate() > 9 ? date.getDate() : `0${date.getDate()}`,
hh = date.getHours() > 9 ? date.getHours() : `0${date.getHours()}`,
mm = date.getMinutes() > 9 ? date.getMinutes() : `0${date.getMinutes()}`;
return `${year}${month}${day}${hh}${mm}`;
},
getAliToken(){ //獲取Token
return new Promise((resolve, reject) => {
this.$axios({
method: 'POST',
url: this.url
}).then(res => {
if (res.success) {
const {expiration, tempAk, tempSk, token} = res.data;
this.expiration = expiration;
this.dataObj = {
region: this.region,
bucket: this.bucket,
accessKeyId: tempAk,
accessKeySecret: tempSk,
stsToken: token
};
resolve(true);
} else {
reject(false);
}
}).catch(err => {
console.log(err);
reject(false);
})
})
},
beforeUpload(file){
return new Promise((resolve, reject) => {
this.getAliToken().then(response => {
if (response) {
resolve(response);
} else {
reject(response);
}
}).catch(err => {
console.log(err);
reject(err);
});
})
},
async handleHttpRequest(option){ //上傳OSS
try {
let vm = this;
vm.disabled = true;
const client = Client(this.dataObj), file = option.file;
//隨機命名
const random_name = this.random_string(6) + '_' + new Date().getTime() + '.' + file.name.split('.').pop();
// 分片上傳文件
await client.multipartUpload(random_name, file, {
progress: async function (p) {
let e = {};
e.percent = p * 100;
option.onProgress(e)
}
}).then(({res}) => {
console.log(res);
if (res.statusCode === 200) {
// option.onSuccess(ret)
return res.requestUrls
} else {
vm.disabled = false;
option.onError('上傳失敗');
}
}).catch(error => {
vm.disabled = false;
option.onError('上傳失敗');
});
} catch (error) {
console.error(error);
this.disabled = false;
option.onError('上傳失敗');
}
},
handleSuccess(response, file, fileList){
console.log(response);
console.log(file);
console.log(fileList);
},
// 隨機生成文件名
random_string(len) {
len = len || 32;
let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz12345678', maxPos = chars.length, pwd = '';
for (let i = 0; i < len; i++) {
pwd += chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
}
},
watch: {
url(val){
if (val) {
this.urls.push(val);
}
}
},
components: {},
computed: {},
watch: {},
created(){
this.getAliToken();
},
mounted(){
},
}
</script>
<style scoped>
/**渲染內容的樣式**/
</style>
完成上傳