vue+ element 使用阿里云oss,腾讯云cos上传视频图片,

一、element 使用腾讯云cos

官方配置文档

1. vue配置腾讯云cos

根据自己需求配置,我是使用最简单官方的文档配置使用方法

(1) 项目安装依赖, npm install cos-js-sdk-v5

(2) 新建一个cos.js

// import moment from 'moment'
import { credential } from '@/api/common'
var COS = require('cos-js-sdk-v5')
export const uploadFileOrPic = async (file, fileName) => {
 // 为了保证桶的数据安全,数据桶的参数需要后端给你传,这样比较安全
 const res = await credential({ bucketKey: 'gas_bucket' })
 const { tmpSecretId, tmpSecretKey, sessionToken, bucketName, region, expiredTime } = res.result
 // 创建桶的实例
 const cos = new COS({
   // 必选参数
   getAuthorization: (options, callback) => {
     const obj = {
       TmpSecretId: tmpSecretId,
       TmpSecretKey: tmpSecretKey,
       XCosSecurityToken: sessionToken,
       ExpiredTime: expiredTime(过期时间) // 时间戳,单位秒,如:1580000900
     }
     callback(obj)
   }
 })
 // 上传图片
 return new Promise((resolve, reject) => {
   // 这里使用最简单的 putObject 方法上传你需要上传的文件。
   cos.putObject({
     Bucket: bucketName, /* 必须 */
     Region: region, /* 存储桶所在地域,必须字段 */
     // Key: `${new Date().getTime()}${fileName}`,
     Key: fileName,
     StorageClass: 'STANDARD',
     Body: file, // 上传文件对象
     onProgress: progressData => {
       console.log(JSON.stringify(progressData))
     }
   }, (err, data) => {
     // 将上传后的封面进行路径拼接保存到本地
     resolve(data)
     reject(err)
   })
 })
}
复制代码

(3) 组件页面使用

    <el-upload :disabled="loading" action="#"  list-type="picture-card" :on-remove='removePic'  :on-preview='preview' :on-change="(file, fileList) => {handleChange(file, fileList)}" :before-upload="file => beforeUpload(file)" accept=".jpg,.jpeg,.png,.mov,.mp4" :file-list="refuseRefundOptions.voucherDirs">
       <i v-loading.lock="loading" class="el-icon-plus avatar-uploader-icon"></i>
    </el-upload>
    
   // 这里用在element的upload,你可以写在change方法,或者 beforeUpload方法,根据业务自己选择。 
   handleChange (file) {
      this.loading = false
      // 这里上传的file记得打印看看,传的对不对
      uploadFileOrPic(file, file.name,).then(res => {
        this.url = `https://${res.Location}`
      }).finally(() => {
        this.loading = false
      })
    },
复制代码

(4)新问题,如果需要上传的是一个大文件,几十上百M,这时候的cos,一旦开始上传就会开一个网络进程,需要时间才能上传上去,如果此时你不想上传了,js没有办法提供中断cos网络进程的方法。怎么办?

腾讯云cos提供了一个专业的方法----cos.uploadFile

实现思路原理:

  • 上传的文件如果小于一个尺寸,就正常上传,大于一个尺寸,就会自动分片处理上传

  • 一旦项目使用分片上传,cos 的 onTaskReady 方法会返回一个taskId,

  • 上传过程中使用cos.cancelTask(taskId), 就可以中断你这次的上传,直接停止,

官方推荐

改良版本 cos.js

// import moment from 'moment'
import { credential } from '@/api/common'
var COS = require('cos-js-sdk-v5')
export const uploadFileOrPic = async (file, fileName, callBackUp) => {
  const res = await credential({ bucketKey: 'gas_bucket' })
  const { tmpSecretId, tmpSecretKey, sessionToken, bucketName, region, expiredTime } = res.result
  const cos = new COS({
    // 必选参数
    getAuthorization: (options, callback) => {
      const obj = {
        TmpSecretId: tmpSecretId,
        TmpSecretKey: tmpSecretKey,
        XCosSecurityToken: sessionToken,
        // StartTime: data.startTime, // 开始时间戳,单位秒
        ExpiredTime: expiredTime // 过期时间戳,单位秒
      }
      callback(obj)
    }
  })
  // 上传图片
  return new Promise((resolve, reject) => {
    cos.uploadFile({
      Bucket: bucketName, /* 必须 */
      Region: region, /* 存储桶所在地域,必须字段 */
      Key: fileName, // 文件名
      StorageClass: 'STANDARD', // 上传类型,可选
      Body: file, // 上传文件对象
      onTaskReady: function(taskId) {
        // 用于中断分片上传回调
        callBackUp && callBackUp({cos,taskId})
      },
      onProgress: function (progressData) {
        console.log(JSON.stringify(progressData));
      },
      onFileFinish: function (err, data, options) {
        console.log(options.Key + '上传' + (err ? '失败' : '完成'));
      },
    }, (err, data) => {
      // 将上传后的封面进行路径拼接保存到本地
      resolve(data)
      reject(err)
    })
  })
}
复制代码

在自定义的 uploadFileOrPic 方法里面 新加一个callBackUp回调地址,用于吧cos上传产生的taskId 回调给组件,方便组件拿到taskId,用于终止

同时在cos.uploadFile实例里面的onTaskReady方法拿到taskId,并且执行callBackUp && callBackUp({cos,taskId}), 把 taskId 和 cos实例全部回调给组件

为什么要返回cos实例给组件?因为中断的方法cancelTask只有cos实例才有,你自己的组件没有的

改良版本组件.vue

handleChange (file) {
  // 这里上传的file记得打印看看,传的对不对
  uploadFile(file, name, taskRes => {
  // taskRes 这个回调返回的值就是我们在cos.js里面传的 cos实例 和 taskId
   this.currTask = taskRes
  }).then(res => {
   this.url = `https://${res.Location}`
  }).finally(() => {
    this.loading = false
  })
},
复制代码

使用 taskRes 这个回调返回的值就是我们在cos.js里面传出去的 cos实例 和 taskId 这样就可以在组件任何时候,直接调用cos.cancelTask(taskId)中断上传

2. 腾讯云后台配置跨域

有时候我们在代码里面配置好了所有的东西,但是还是无法上传,控制台报一个跨域的错误。这时候在腾讯云配置一下项目的域名就可以了。

  1. 登录腾讯云找到 对象存储 管理后台

管理后台

  1. 找到跨域cos配置,添加规则(来源origin,就使用目前项目的域名,本地,测试,线上域名都配置一下)

比如:

 *.xxx.com
 http://127.0.0.1:*
 http://localhost:*
复制代码

操作methods全部勾上

添加规则

再试一下是不是就可上传了

3. 腾讯云后台配置Referer白名单

有时候上传完成以后,拿着cos返回给你的链接,无法在新打开的浏览器标签直接打开,这是因为需要设置Referer白名单

配置Referer白名单 Refer文本框就写你需求打开的项目的域名

空refer允许空,空白标签也能打开

4. element upload上传视频缩略图展示

开发过程中有这种需求,产品要求使用element的upload组件,实现支持视频和图片上传且支持预览,图片上传没有啥问题。可以正常展示缩略图,但是视频上传之后,缩略图无法展示,这个时候就需要吧cos返回的视频连接第一帧截取出来当做第一帧展示,

一般情况下返回的视频链接: https://xin-test-1257039795xxxxx/xxxx/xxxxx.mp4

只要在这个链接后面拼接上一串字符串机就可以实现截取第一帧的图片,从而在element展示缩略图

https://xin-test-1257039795xxxxx/xxxx/xxxxx.mp4?x-oss-process=video/snapshot,t_10000,m_fast (阿里官方提供的字符串)

或者

https://xin-test-1257039795xxxxx/xxxx/xxxxx.mp4?ci-process=snapshot&time=1 (腾讯官方提供的字符串) cos视频第一帧文档

二、element 使用阿里云oss

阿里云cos配置跟腾讯云大同小异,根据官网配置都能做到(阿里云网上资料更多)

npm install ali-oss

1. vue配置阿里云oss

oss.js

这是我们项目配置的,能满足基本功能,有更好的更优雅的不建议使用。

import moment from 'moment'
import { ossToken } from '../api/common'
let OSS = require('ali-oss')
// isStamp 加时间戳,避免同名文件覆盖
export const uploadFile = async (file, fileName, type = 'other', isStamp = true) => {
  const res = await ossToken({ bucketName: 'weber-imgs' })
  const { accessKeyId, accessKeySecret, securityToken } = res.result
  let client = new OSS({
    accessKeyId: accessKeyId,
    accessKeySecret: accessKeySecret,
    stsToken: securityToken,
    bucket: 'weber-imgs',
    region: 'oss-cn-beijing',
    secure: true
  })
  try {
    let env = 'test'
    if (process.env.VUE_APP_ENV === 'production') {
      env = 'pro'
    }
    let result = ''
    if (isStamp) {
      result = await client.put(`ty/hela/${env}/${type}/${moment().format('YYYYMMDD')}/${Date.now()}${fileName}`, file)
    } else {
      result = await client.put(`ty/hela/${env}/${type}/${fileName}`, file)
    }
    return result
  } catch (e) {
    console.log(e)
  }
}

复制代码

组件使用

    // 上传到oss
    async handleChange () {
      this.uploading = true
      try {
        const res = await uploadFile(this.file, this.fileName, 'file', false)
        if (res.url) {
          // 保存URL
          this.form.iconUrl = res.url
        } else {
          this.$message.error('上传失败,请重试!')
        }
      } catch (e) {
        this.$message.error('上传失败,请重试!')
      } finally {
        this.uploading = false
      }
    },
复制代码

2. 阿里云后台配置跨域

找到阿里云域名配置,跟cos一样的

3. 阿里云后台配置Referer白名单

找到阿里云域名配置,跟cos一样的

4. element upload上传视频缩略图展示

同理获取第一帧缩略图

https://xin-test-1257039795xxxxx/xxxx/xxxxx.mp4?x-oss-process=video/snapshot,t_10000,m_fast (阿里官方提供的字符串)

猜你喜欢

转载自juejin.im/post/7018760355056713742