Vue上傳阿里雲OSS(STS方式)

一、準備工作

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

關於直傳,阿里官方給了三種方案:

  1. 客戶端 JavaScript 簽名後直傳;
  2. 客戶端申請服務端簽名,然後打包上傳;
  3. 客戶端申請服務端簽名,打包上傳OSS後回調服務端。

這裏使用第一種。

vue中使用步驟:

  1. 在src目錄中創建utils文件夾
  2. utils文件夾中創建Client.js
  3. 在組件中創建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>

 

完成上傳

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章