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

1.需求:将文件上传至腾讯云私有数据库

步骤:

  1. 安装腾讯云sdk(现在是cos-js-sdk-v5)
  2. 获取临时身份凭证token,该token被设置为1小时有效
  3. 拿到临时身份凭证后上传文件
  4. 将上传后的文件id或者url(看后端需要什么数据)传给后端,在数据库中保存
  5. 由于是私有库,需要对显示的文件在下载的时候去获取真正的文件地址(如果是共有库,这一步省略)

2.上传至腾讯云

// html 代码
    <el-upload
      action
      :http-request="getSignToken"
      :data="fileType"
      :on-change="change"
      :before-upload="beforeUpload"
      :on-remove="handleRemove"
      multiple
      :limit="element.options.length"
      :headers="element.options.headers"
      :on-exceed="handleExceed"
      :file-list="dataModel"
      :disabled="element.options.disabled"
      :style="{'width': element.options.width}"
    >
      <div v-if="!preview">
        <el-button size="small" type="primary">点击上传</el-button>
      </div>
    </el-upload>



// js 代码
import COS from 'cos-js-sdk-v5'
import jsCookie from 'js-cookie'

  async getSignToken(fileOption) {
      let credentials = jsCookie.getJSON('uploadToken')
      if (!credentials) {
      // GETuploadToken 是后端写的接口,去获取临时身份凭证
        const { data } = await GETuploadToken() 
        // 确保token有效期是一个小时内
        var inFifteenMinutes = new Date(new Date().getTime() + 1 * 60 * 59 * 1000)
        jsCookie.set('uploadToken', data, { expires: inFifteenMinutes })
        credentials = data
      }

      if (!credentials) {
        jsCookie.remove('uploadToken')// 删除userInfo
        return this.$message.error('无效上传凭证,请刷新重试')
      }
      const cos = new COS({
      // 这一步是验证临时身份凭证
        getAuthorization: async(options, callback) => {
          callback({
            TmpSecretId: credentials.access_key_id,
            TmpSecretKey: credentials.access_key_secret,
            SecurityToken: credentials.security_token,
            StartTime: ~~(new Date().valueOf() / 1000),
            // 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
            ExpiredTime: credentials.expired_time, // 时间戳,单位秒,如:1580000900
            ScopeLimit: true // 细粒度控制权限需要设为 true,会限制密钥只在相同请求时重复使用
          })
        }
      })
      const url = credentials.upload_dir + '/' + fileOption.file.name
      // 验证通过,此处开始上传文件
      cos.putObject({
        Bucket: credentials.bucket, /* 必须 */
        Region: 'ap-shenzhen', /* 存储桶所在地域,需要后端提供 */
        Key: url, /* 必须 */
        Body: fileOption.file, // 上传文件对象
        onProgress: function(progressData) {
          this.$message.warning('正在上传,请稍后……')
          console.log(progressData, 'progressData')
        }
      }, (err, data) => {
        console.log(err || data)
        if (data.statusCode === 200) {
          fileOption.url = url
          fileOption.status = 'success'
          this.handleSuccess(fileOption)
          return
        }
        console.log(`上传失败,原因:${err}`)
        this.$message.error(`上传失败,请重试`)
      })
    },

3.从腾讯云上下载文件

// html
		<a  href="javascript:void(0)" 
		:download="link.name" 
		@click="downloadFile(link)">  
		{{ link.name }}
		</a>
// js
    async downloadFile({ url, name, type }) {
      this.$message.warning('下载中,请稍后……')
      // GETdownloadUrl 是依据后端给的接口写的函数,去获取动态的真正文件地址
      const { data: fileUrl } = await GETdownloadUrl({ object_key: url })
      if (type.indexOf('image') > -1) {
        const image = new Image()
        image.src = fileUrl
        // 解决跨域 Canvas 污染问题 解决跨域问题-并不好使,需要改对应的请求服务器
        image.setAttribute('crossOrigin', 'anonymous')
        image.onload = function() {
          const canvas = document.createElement('canvas')
          canvas.width = image.width
          canvas.height = image.height

          const context = canvas.getContext('2d')
          context.drawImage(image, 0, 0, image.width, image.height)
          const url = canvas.toDataURL('image/png')

          // 生成一个a元素
          const a = document.createElement('a')
          // 创建一个单击事件
          const event = new MouseEvent('click')

          // 将a的download属性设置为我们想要下载的图片名称,若name不存在则使用‘下载图片名称’作为默认名称
          a.download = name || '下载图片名称'
          // 将生成的URL设置为a.href属性
          a.href = url

          // 触发a的单击事件
          a.dispatchEvent(event)
        }
        return
      }
	// 由于跨域,a标签的dowmload失效,需要XMLHttpRequest去解决问题
      var x = new XMLHttpRequest()
      x.open('GET', fileUrl, true)
      x.responseType = 'blob'
      x.onload = function(e) {
        // 会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。
        var url = window.URL.createObjectURL(x.response)
        var a = document.createElement('a')
        a.href = url
        a.download = name
        a.click()
      }
      x.send()
    },


4.参考

腾讯云sdk文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值