Vue upload Alibaba Cloud OSS (STS method)

1. Preparation

1. Open the Alibaba Cloud OSS service, and obtain the AccessKeyId and AccessKeySecret from the console.

2. Create a bucket and log in to the OSS console

3. Configure Bucket (very important)

  • Set allowed origins to *
  • Set allowed methods (allowed methods) to PUT, GET, POST, DELETE, HEAD
  • Set allowed headers (allowed headers) to *
  • Set expose headers (exposing headers) to ETag (need to wrap here) x-oss-request-id

 

 

You can refer to Ali official documents: https://help.aliyun.com/docum...

2. Introduce ali-oss

There are two ways:

1. Include the following tags in the <head> of the HTML file:

<script src="http://gosspublic.alicdn.com/aliyun-oss-sdk-6.0.1.min.js"></script>

2. Install ali-oss in the project

npm install ali-oss --save

You can refer to Ali official documents: https://github.com/ali-sdk/al...

The second one is used here.

Three, use OSS

Regarding direct transmission, Ali officially gave three solutions:

  1. Client-side JavaScript signed and transmitted directly;
  2. The client applies for the server's signature, and then packs and uploads;
  3. The client applies for the signature of the server, and the server is called back after the package is uploaded to OSS.

The first one is used here.

Use steps in vue:

  1. Create a utils folder in the src directory
  2. Create Client.js in the utils folder
  3. Create testUpload.vue file in the component
//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>

 

Complete upload

 

Guess you like

Origin blog.csdn.net/qq_35775675/article/details/92797782