vue 上传文件到 阿里云OSS,并获取上传进度

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue 上传文件到 阿里云OSS,并获取上传进度相关的知识,希望对你有一定的参考价值。

参考技术A 1.首先,安装阿里的包

初始化一下配置,传的参数data从后台获取

2.使用element-ui的Upload作为上传组件,http-request 来绑定自定义上传的方法Upload,action写为空。 :before-upload="beforeUpload" 表示在上传前做的事情,绑定了方法beforeUpload,我们可以在这个方法里获取所需要的一些信息,比如签名等等

data 例子如下

3.methods
从后台获取第一步所需的数据

上传方法

至此,上传完成

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>

 

完成上传

 

以上是关于vue 上传文件到 阿里云OSS,并获取上传进度的主要内容,如果未能解决你的问题,请参考以下文章

阿里云 oss 小文件上传进度显示

javascript 上传文件到阿里云的oss,上传文件成功后怎么获取文件的真实路径?

Vue上传阿里云OSS(STS方式)

vue页面传值能传图片吗

vue+Springboot上传oss阿里云并回显到前端页面

vue+Springboot上传oss阿里云并回显到前端页面