vue前端上傳檔案到阿里雲oss的兩種方式,put檔案流上傳,multipartUpload直接上傳

流年朝朝發表於2018-07-06

引入阿里雲oss的js

<script src="https://gosspublic.alicdn.com/aliyun-oss-sdk-4.4.4.min.js"></script>
<input type="file" name="file" @change=`selectFile` multiple="multiple"/>上傳圖片/檔案
mounted () {
  this.initConfig() // 呼叫後臺介面獲取阿里雲上傳下載通行證
}
methods: {
  initConfig () {
    // 初始化oss許可權
    let url = `document.getAccess`
    let params = {
       type: `H`
    }
    this.$api.send(url, params).then((response) => {
      if (response.status === 200) {
        let data = response.body.data.data
        /* global OSS */ // 去掉esllint對OSS的校驗
        this.client = new OSS.Wrapper({
          region: `oss-cn-shenzhen`,
          accessKeyId: `your accessKeyId`,
          accessKeySecret: `your accessKeySecret`,
          stsToken: `your stsToken`,
          bucket: `xx`
       })
     }
   })
  },
  selectFile (e) {
    // 選擇檔案
    for (let i = 0; i < e.target.files.length; i++) {
      this.pushFile(e.target.files[i])
    }
  },
  pushFile (file) {
    let that = this
    let _file = file
    var storeAs = `` // 傳到oss上的名字
    // 呼叫上傳方法
    that.client.multipartUpload(`cloudStorage/` + storeAs, _file, {
      progress: function* (percentage) {
        let fileloadingNum = Math.ceil(percentage * 100) + `%`
        console.log(fileloadingNum) // 上傳檔案進度
      }
    }).then(function (result) {
      // 呼叫後臺新增檔案的介面
      let url = `netdisc.addDoc`
      let params = {
        data: `xx`
      }
      that.$api.send(url, params).then((response) => {
        if (response.status === 200) {
          // 上傳成功
        }
      })
    }).catch(function (err) {
      // 上傳失敗,彈出上傳失敗的訊息
    })
  }
}

如果傳到阿里雲的圖片要展示出來,要在src的圖片路徑後面加上阿里雲字尾,這樣用蘋果手機拍的照片就不會出現圖片翻轉的問題,像這樣
xxx.JPG?x-oss-process=image/auto-orient,1/resize,m_fill,w_1600

如果圖片要用canvas做壓縮, 得到的是base64資料,要轉換成blob物件,再轉為buffer流。用put上傳
有些手機不支援canvas直接轉為blob物件可以引入canvas-to-blob.min.js 將canvas轉為blob物件
blob外掛地址: https://github.com/blueimp/Ja…
獲得圖片的方向,引入exif.js
exif.js 官網地址 http://code.ciaoca.com/javasc…
專案中都是用<script>標籤直接在index.html中引用的

  pushFile (file) {
    let that = this
    if ([`jpeg`, `png`, `jpg`].indexOf(file.type.split(`/`)[1]) < 0) {
      alert(`只支援jpg/png格式的圖片`)
      return false
    }
    // orient=>照片的角度
    /* global EXIF */
    let orient
    EXIF.getData(file, function () {
      orient = EXIF.getTag(this, `Orientation`)
    })
    // 壓縮圖片需要的一些元素和物件
    let reader = new FileReader()
    let img = new Image()
    // 選擇得是圖片
    if (file.type.indexOf(`image`) === 0) {
      reader.readAsDataURL(file)
    }
    // 縮放圖片需要的canvas
    let canvas = document.createElement(`canvas`)
    let context = canvas.getContext(`2d`)
    // base64 地址載入完後
    img.onload = function () {
      // 圖片原始尺寸
      let originWidth = this.width
      let oringinHeight = this.height
      // 最大尺寸限制
      let maxWidth = 800
      let maxHeight = 800
      // 目標尺寸
      let targetWidth = originWidth
      let targetHeight = oringinHeight
      // 圖片尺寸超過800x800的限制
      if (originWidth > maxWidth || oringinHeight > maxHeight) {
        if (originWidth / oringinHeight > maxWidth / maxHeight) {
          // 更寬
          targetWidth = maxWidth
          targetHeight = Math.round(maxWidth * (oringinHeight / originWidth))
        } else {
          targetHeight = maxHeight
          targetWidth = Math.round(maxHeight * (originWidth / oringinHeight))
        }
      }
      // canvas 對圖片進行縮放
      canvas.width = targetWidth
      canvas.height = targetHeight
      // 清除畫布
      context.clearRect(0, 0, targetWidth, targetHeight)
      // 圖片壓縮
      context.drawImage(img, 0, 0, targetWidth, targetHeight)
      if (orient !== `` && orient !== 1) {
        // orient === 1是正常的
          switch (orient) {
            case 6: // 需要順時針向左90度旋轉
              that.rotateImg(img, `left`, canvas, targetWidth, targetHeight)
              break
            case 8: // 需要逆時針向右90度旋轉
              that.rotateImg(img, `right`, canvas, targetWidth, targetHeight)
              break
            case 3: // 需要180度旋轉
              that.rotateImg(img, `right`, canvas, targetWidth, targetHeight)
              that.rotateImg(img, `right`, canvas, targetWidth, targetHeight)
              break
          }
        }
        if (canvas.toBlob) {
          canvas.toBlob(function (blob) {
            // 在這裡實現上傳操作
            let reader2 = new FileReader()
            reader2.readAsArrayBuffer(blob)
            reader2.onload = function (event) {
              let buffer = new OSS.Buffer(event.target.result)
              that.client.put(storeAs, buffer).then((result) => {
                if (result.url) {
                  // 獲得圖片地址
                  that.src= result.url
                }
              }).catch((err) => {
                console.log(err)
                alert(`上傳失敗, 請重新上傳`)
              })
            }
          }, file.type || `image/png`)
        }
      }
    rotateImg (img, direction, canvas, targetWidth, targetHeight) {
      // 最小與最大旋轉方向,圖片旋轉4次後回到原方向
      var minstep = 0
      var maxstep = 3
      if (img === null) return
      // img的高度和寬度不能在img元素隱藏後獲取,否則會出錯
      var step = 2
      if (step === null) {
        step = minstep
      }
      if (direction === `right`) {
        step++
        // 旋轉到原位置,即超過最大值
        step > maxstep && (step = minstep)
      } else {
        step--
        step < minstep && (step = maxstep)
      }
      // 旋轉角度以弧度值為引數
      let degree = step * 90 * Math.PI / 180
      var ctx = canvas.getContext(`2d`)
      switch (step) {
        case 0:
          canvas.width = targetWidth
          canvas.height = targetHeight
          ctx.clearRect(0, 0, targetWidth, targetHeight)
          ctx.drawImage(img, 0, 0, targetWidth, targetHeight)
          break
        case 1:
          canvas.width = targetHeight
          canvas.height = targetWidth
          ctx.rotate(degree)
          ctx.clearRect(0, 0, targetHeight, targetWidth)
          ctx.drawImage(img, 0, -targetHeight, targetWidth, targetHeight)
          break
        case 2:
          canvas.width = targetWidth
          canvas.height = targetHeight
          ctx.rotate(degree)
          ctx.clearRect(0, 0, targetWidth, targetHeight)
          ctx.drawImage(img, -targetWidth, -targetHeight, targetWidth, targetHeight)
          break
        case 3:
          canvas.width = targetHeight
          canvas.height = targetWidth
          ctx.rotate(degree)
          ctx.clearRect(0, 0, targetHeight, targetWidth)
          ctx.drawImage(img, -targetHeight, 0, targetWidth, targetHeight)
          break
      }
    }
  }

相關文章