vue前端腾讯云cos对象存储使用

399 阅读2分钟

使用场景:利用腾讯云cos对象存储,上传图片等小型文件

第一步:装包

npm i cos-js-sdk-v5 --save

第二步:新建COS配置文件,main.js文件中引入

import Vue from 'vue'
var COS = require("cos-js-sdk-v5");
let cos = {
    ok: false,
    Region: '',
    Bucket: '',
    www: '',
    obj: '',//腾讯云对象
    init: function (Region, Bucket, www) {
        if (Region && Bucket) {
            this.Region = Region
            this.Bucket = Bucket
            this.www = www
            this.obj = new COS({
                // getAuthorization 必选参数 
                getAuthorization: function (options, callback) {
                    // 异步获取临时密钥 首次上传会首选获取密钥配置到COS对象中
                    // 服务端 JS 和 PHP 例子:https://github.com/tencentyun/cos-js-sdk-v5/blob/master/server/
                    // 服务端其他语言参考 COS STS SDK :https://github.com/tencentyun/qcloud-cos-sts-sdk
                    // STS 详细文档指引看:https://cloud.tencent.com/document/product/436/14048       
                    var url =
                        process.env.VUE_APP_BASE_API +
                        process.env.VUE_APP_API_PATH +
                        "后端获取密钥的接口地址"; // url替换成您自己的后端服务
                    var xhr = new XMLHttpRequest();
                    xhr.open("GET", url, true);
                    const token = sessionStorage.getItem("token");
                    xhr.setRequestHeader("Authorization", token);
                    xhr.onload = function (e) {
                        var data = "";
                        var credentials = "";
                        try {
                            data = JSON.parse(e.target.responseText);
                            credentials = data.data.credentials;
                        } catch (e) { }
                        if (!data || !credentials) {
                            return console.error(
                                "credentials invalid:\n" +
                                JSON.stringify(data, null, 2)
                            );
                        }
                        callback({
                            TmpSecretId: credentials.tmpSecretId,
                            TmpSecretKey: credentials.tmpSecretKey,
                            SecurityToken: credentials.sessionToken,
                            // 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
                            StartTime: data.data.startTime, // 时间戳,单位秒,如:1580000000
                            ExpiredTime: data.data.expiredTime, // 时间戳,单位秒,如:1580000000
                        });
                    };
                    xhr.send();
                },
            });
            this.ok = true
        }
    },
    //上传方法
    putObject: function (file, channel, onProgress, onSuccess, onError, onFinish) {
        let fileName = this.getfileName(file, channel)
        this.obj.putObject({
            Bucket: this.Bucket /* 必须 */,
            Region: this.Region /* 存储桶所在地域,必须字段 */,
            Key: fileName /* 必须 */,
            // StorageClass: 'STANDARD',
            Body: file, // 上传文件对象
            onProgress: onProgress
        }, (err, data) => {
            if (err) {
                typeof onError == 'function' && onError(err)
            } else if (data) {
                if (data.statusCode == 200) {
                    let url = this.www + '/' + fileName
                    typeof onSuccess == 'function' && onSuccess(url, data)
                    } else {
                        typeof onError == 'function' && onError(data)
                    }
            }
            typeof onFinish == 'function' && onFinish(err, data)
        })
    },
    //获取文件名称 根据具体业务设置文件名称
    getfileName(file, channel) {
        let user = JSON.parse(sessionStorage.getItem('user'))
        return `${channel}-${user.id}-${new Date().getTime()}${this.getSuffix(file)}`
    },
    //获取文件格式(后缀)
    getSuffix(file) {
        let name = file.name
        if (typeof name == 'string') {
            let a = name.split('.')
            if (a[a.length - 1]) {
                return '.' + a[a.length - 1]
            } else {
                return ''
            }
        } else {
            return ''
        }
    }
}
Vue.use({
    install: Vue => Vue.prototype.$cos = cos
})
export default cos;

第三步:页面加载初始化cos

//初始化cos,获取存储桶用户识别(Bucket)以及地区识别(Region)、域名(www),调用$cos.init()进行初始化
initCos() {
    this.$http.get("后端地址").then((res) => {
        if (res.body.code == 200) {
            this.$cos.init(
                res.body.data[0],
                res.body.data[1],
                res.body.data[2]
            );
        }
    });
},

第四步:组件调用cos上传方法

this.$cos.putObject(
    result,//文件file对象
    "driverCard",//渠道名称
    (progress) => {
        console.log(progress);
    }, 
    (url, data) => {
        console.log('上传成功');
    },
    (err) => {
        console.log(err);
    },
    (err, data) => {
        console.log('finish');
    }
);

拓展:重要文件例如身份证、驾驶证、营业执照等证件照片,一般会存储到私有桶里面,需要后端提供新的接口把以上初始化时存储桶(Bucket)的地址、临时密钥全部替换为私有的即可,然后通过cos上传返回的url就无法正常访问图片了,需通过cos返回的url去后端请求获取临时访问地址。

有时会出现跨域问题,一般是腾讯云配置原因,后台配置跨域即可。