cos上传

使用vue 结合 腾讯cos实现上传图片

cos

cos客户端:https://cloud.tencent.com/document/product/436/11366
cos入门:https://cloud.tencent.com/document/product/436/11459
借鉴:https://www.jb51.net/article/161251.htm

js代码

  • 安装依赖包
npm install cos-js-sdk-v5
  • 使用 axios 来请求接口
  • 代码 封装 cos.js 文件
import CosCloud from "cos-js-sdk-v5"
import axios from 'axios'

// 上传文件(调用相关api putObject来上传文件)
/**
 * @method uploadFile
 * @param {object} cos
 */
function uploadFile(cos, file, signInfo, callback) {
  // name: 图片的名称,可以自定义,这里为了不覆盖相同名照片,使用了时间戳
  let name = `/store/st/${new Date().valueOf()}`
  let pic = ''
  // Bucket: 存储桶  Bucket 的名称,命名规则为 BucketName-APPID,此处填写的存储桶名称必须为此格式
  // Region:Bucket 所在地域,枚举值请参阅 地域和访问域名:https://cloud.tencent.com/document/product/436/6224
  cos.putObject(
    {
      Bucket: 'marryparty-1253457213',
      Region: 'ap-guangzhou',
      Key: `${name}`,
      Dir: 'store',
      Body: file,
      onHashProgress: function (progressData) {
        console.log('校验中', JSON.stringify(progressData));
      },
      onProgress: function (progressData) {
        console.log('上传中', progressData)
        if (progressData.percent === 1) {
          // 上传完执行操作  这里将图片的 pic 作为图片的src 抛出去,在调用的地方用res.pic获取即可
          pic = `http://marryparty-1253457213.cos.ap-guangzhou.myqcloud.com${name}`
        }
      },
    },
    function (err, data) {
      console.log(data)
      if (err) {
        callback({ success: false, msg: '文件上传失败!' });
        return;
      }
      // 上传成功把数据抛出去, pic 是上文的图片的链接
      callback({ success: true, msg: '上传成功!', data: data, signInfo: signInfo, pic: pic });
    }
  )
}
// 获取文件上传密钥(最好存在后端通过ajax请求获取,安全性较高)
function getFileToken(Vue, fileInfo, cos, file, uploadStatusCallbalck) {
  // 秘钥是请求后台的接口,替换即可
  // 正式环境会自动加域名
  let url = '/manage/store-api/get_ticket'
  // 本地
  // let url = 'https://store.ihuyue.cn/manage/store-api/get_ticket'  
  if (!file) return;
  // 异步获取临时密钥
  axios
    .get(url)
    .then(function (res) {
      if (res.data.ret == 0) {
        //获取的临时秘钥存储在vuex中
        Vue.$store.commit('setUPDATEFILEINFO', res.data.data);
        uploadFile(cos, file, res.data.data, uploadStatusCallbalck);
      } else {
        uploadStatusCallbalck({ success: false, msg: '获取文件秘钥失败!' });
      }
    })
    .catch(function (err) {
      uploadStatusCallbalck({ success: false, msg: '获取文件秘钥接口出错!' });
    });
}
/**
 * 初始化上传文件对象
 * @param {object} Vue
 * @param {string} fileName 文件名
 * @param {object} file 上传的文件流及文件类型 名称相关信息
 * @param {Array} 允许上传的文件类型
 * @param {function} uploadStatusCallbalck
 * @return {function} 返回回调函数
 */
export const initUploadObj = function (Vue, fileName, file, type, uploadStatusCallbalck) {
  let fileInfo = {
    file_name: fileName,
    media_type: 2,
    media_sub_type: 0,
    size_of_bytes: 122,
    file_expired_type: 'permanent',
  };
  console.log(file, 'file---------')
  // 上传图片大小做限制
  if (file.size > 2048) {
    Vue.$Message.error('请上传小于2M的图片!')
    return
  }
  //前端做文件类型限制
  if (type == 'image') {
    type = ['.jpg', '.gif', '.jpeg', '.bmp', '.png']
  }
  if (type == 'excel') {
    type = ['.xlsx']
  }
  let fileType = file.name ? file.name.substring(file.name.lastIndexOf(".")).toLowerCase() : '';
  if (!!type && type.indexOf(fileType) < 0) {
    uploadStatusCallbalck({ success: false, msg: '请上传正确的' + type + '文件格式!' })
    return
  }
  var cos = new CosCloud({
    getAuthorization: function (options, callback) {
      let singleInfo = Vue.$store.state.app.fileToken;
      callback({
        TmpSecretId: singleInfo.credentials.tmpSecretId,
        TmpSecretKey: singleInfo.credentials.tmpSecretKey,
        XCosSecurityToken: singleInfo.credentials.sessionToken,
        ExpiredTime: singleInfo.expiredTime,
      });
    },
  });
  fileInfo.file_name = file.name
  //获取文件上传密钥
  getFileToken(Vue, fileInfo, cos, file, uploadStatusCallbalck);
}

export default initUploadObj

使用

  • html 这里只上传一张图片,可以根据自己需要修改
修改头像
上传图片的宽高比必须满足1:1,否则无法上传!建议图片尺寸为130 * 130。(最大不超过2M)
  • 这里把css也贴出来,方便看效果
.l-pic {
  width: 100%;
  display: flex;
  .upload-img {
    position: relative;
    height: 100px;
    .up-img {
      width: 100px;
      height: 100px;
    }
    .up-change {
      position: absolute;
      bottom: 0;
      left: 0;
      width: 100px;
      height: 20px;
      line-height: 20px;
      text-align: center;
      color: #fff;
      background: rgba(0, 0, 0, .4);
      .up-input {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        outline: none;
        opacity: 0;
        z-index: 3;
      }
    }
  }
  .up-block {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100px;
    height: 100px;
    border: 1px dashed #ccc;
    .up-input {
      position: absolute;
      top: 0;
      left: 0;
      width: 100px;
      height: 100px;
      outline: none;
      opacity: 0;
      z-index: 3;
    }
  }
  .msg {
    color: rgb(45, 140, 240);
    margin-left: 10px;
  }
}
  • js
import initUploadObj from '@/libs/cos'

uploadImg() {
  let that = this
  let file = document.querySelector('input[type=file]').files[0]
  let type = file.type
  //初始化文件上传
  initUploadObj(that, file.name, file, 'image', function(res) {
    if (res.success) {
      // 这里res是cos里返回的数据
      console.log(res.pic)
      // 上传图片比例限制
      let img = new Image()
      img.src = res.pic
      img.onload = function(){
        let w = img.width
        let h = img.height
        if (w != h) {
          that.$Message.error('请按照规定的宽高比上传图片!')
          return
        } else {
          that.formValidate.header = res.pic
          that.formValidate = JSON.parse(JSON.stringify(that.formValidate))
        }
      }
    } else {
      this.$Message.error('图片上传失败')
    }
  })
},

你可能感兴趣的:(cos上传)