Vue+ElementUI+Axios+腾讯云对象存储实现图片上传

一篇简单的踩坑日记;
坑点: 官方demo无法拿到请求响应;
解决方案: 根据demo,将请求单独抽离出来;

官方demo如下:

// 初始化实例
var cos = new COS({
    getAuthorization: function (options, callback) {
        // 异步获取临时密钥
        $.get('http://example.com/server/sts.php', {
            bucket: options.Bucket,
            region: options.Region,
        }, function (data) {
            var credentials = data && data.credentials;
            if (!data || !credentials) return console.error('credentials invalid');
            callback({
                TmpSecretId: credentials.tmpSecretId,
                TmpSecretKey: credentials.tmpSecretKey,
                XCosSecurityToken: credentials.sessionToken,
                // 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
                StartTime: data.startTime, // 时间戳,单位秒,如:1580000000
                ExpiredTime: data.expiredTime, // 时间戳,单位秒,如:1580000900
            });
        });
    }
});

由于官方demo并没有采用ES6,所以首先要对某部分的代码按照ES6进行改造,例如箭头函数;采用vue之后,由于ESlint并不支持如demo中的callback回调直接赋予一个对象,将对象在callback之前用一个常量存储起来,再将这个常量赋予callback即可解决ESlint报错的问题;

改造之后的流程如下:
1、需要使用的依赖
axios、elementui的upload组件、cos-js-sdk-v5

npm i axios
npm i cos-js-sdk-v5
import vue from 'vue'
import { Upload } from 'element-ui'
vue.use(Upload)
<el-upload style="margin-left:50%;transform:translateX(-74px)"
action="#"
:http-request="uploadImg"
:limit='1'
list-type="picture-card"
:on-change="changeHandel"
:auto-upload="true">
  <span id="text">点击上传封面</span>
</el-upload>

2、通过upload绑定的事件,拿到选中的图片对象

data () {
    return {
      // 修改作品信息弹窗显示与否
      dialogVisible: false,
      // 图片文件
      imgFile: '',
      // 图片文件名称
      fileName: '',
      // 上传成功后的地址
      imgURL: '',
    }
  },
// 获取封面对象
    changeHandle (file, fileList) {
      console.log(file)
      this.imgFile = file
      this.fileName = file.name
      // 上传之后将上传封面隐藏,避免频繁操作
      const upload = document.getElementById('text')
      const parent = upload.parentNode
      parent.style.display = 'none'
    },
    //请忽略我傻逼式的DOM操作

3、获取签名,完成上传
按照官方demo去获取签名,完全得不到半点服务器的回应,所以做了部分改造,各位自行比对;

// 封面上传
   async uploadImg () {
      // 创建COS实例  获取签名
      //这里写你们后端提供的请求接口即可
      const res = await this.$axios.get('/xxxxxxxx/xxxxxxxx')
      // console.log(JSON.parse(res.data.data))
      //这里是因为我们后端返回的是一组JSON字符串,所以进行了一次转化,如果你们直接返回的就是json对象,直接忽略即可
      const data = JSON.parse(res.data.data)
      const cos = new COS({
        // 必选参数
        getAuthorization: (options, callback) => {
          const obj = {
            TmpSecretId: data.credentials.tmpSecretId,
            TmpSecretKey: data.credentials.tmpSecretKey,
            XCosSecurityToken: data.credentials.sessionToken,
            StartTime: data.startTime, // 时间戳,单位秒,如:1580000000
            ExpiredTime: data.expiredTime // 时间戳,单位秒,如:1580000900
          }
          callback(obj)
        }
      })
      // 上传图片  其中Bucket 和 Region找你们负责人拿
      //key 在前面加上路径写法可以生成文件夹
      cos.putObject({
        Bucket: 'sike-123456789', /* 必须 */
        Region: 'ap-chongqing', /* 存储桶所在地域,必须字段 */
        Key: '/img/' + new Date().getTime() + this.fileName, /* 必须 */
        StorageClass: 'STANDARD',
        Body: this.imgFile.raw, // 上传文件对象
        onProgress: progressData => {
          console.log(JSON.stringify(progressData))
        }
      }, (err, data) => {
        // 将上传后的封面进行路径拼接保存到本地
        console.log(err || data)
        const url = 'https://' + data.Location
        // console.log(url)
        this.imgURL = url
      })
    },

最后附上成品样式:
忽略名称即可

总结: 将请求单独拿出来,不使用官方demo的请求方式;

猜你喜欢

转载自blog.csdn.net/ljy_1024/article/details/111478370