cos上传

作者: cjcjcjcj | 来源:发表于2019-07-04 17:31 被阅读0次

    使用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 这里只上传一张图片,可以根据自己需要修改
    <div class="l-pic">
      <div v-if="formValidate.header"  class="upload-img">
        <img class="up-img" :src="formValidate.header">
        <div class="up-change">
          <div>修改头像</div>
          <input class="up-input" type="file" id="file" @change="uploadImg()" />
        </div>
      </div>
      <div v-else class="up-block">
        <Icon type="ios-add" size="25" />
        <input class="up-input" type="file" id="file" @change="uploadImg()" />
      </div>
      <div class="msg">上传图片的宽高比必须满足1:1,否则无法上传!建议图片尺寸为130 * 130。(最大不超过2M)</div>
    </div>
    
    • 这里把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上传

        本文链接:https://www.haomeiwen.com/subject/cknrhctx.html