上传的图片以文件流形式返回后,前端在不同浏览器中预览兼容性问题处理

191 阅读1分钟

在工作中,遇到一个问题,就是上传的图片在不同浏览器下无法下载,图片无法预览, 项目使用的是Vue + Elementui

<draggable class="drag-img-list"
  v-model="fileList"
  v-bind="{group: uploadId, ghostClass: 'ghost', animation: 200}"
  :no-transition-on-drag="true"
>
  <div 
    :id="item.key"
    :style="{width: width+'px', height: height+'px'}"
    :class="{uploading: item.status=='uploading', 'is-success': item.status=='success', 'is-disabled': disabled}"
    class="upload-file" v-for="(item) in fileList" :key="item.key">
    <img :src="item.url" />

</draggable>



在这里的img使用的是后台返回的item.url(为一个http链接,通过链接可以查看图片), 由于存在安全问题,将此返回为文件流

此时在谷歌上传的文件在其他浏览器就无法下载了

为了解决此问题,需要将文件流转为base64,但是转为base64在存储的话,字符太长,后台接收有问题,因此这个时候需要给img动态设置url,在当前的fileList上保留url

  <draggable class="drag-img-list"
      v-model="fileList"
      v-bind="{group: uploadId, ghostClass: 'ghost', animation: 200}"
      :no-transition-on-drag="true">
  <div 
    :id="item.key"
    :style="{width: width+'px', height: height+'px'}"
    :class="{uploading: item.status=='uploading', 'is-success': item.status=='success', 'is-disabled': disabled}"
    class="upload-file" v-for="(item, index) in fileList" :key="item.key">
    <img :ref="'imgRef'+index" />
   </draggable>
  
  
  watch: {
    fileList: {
      deep:true,
      handler(newVal, oldVal) {
        if(newVal.length!==0) {
        this.$nextTick(() => {
          for (let index = 0; index < newVal.length; index++) {
            this.getImgUrl(newVal[index], index) 
          }
        })

        }
      }
    }
   },
   methods: {
    getImgUrl(item, index) {
      let _this  = this
      this.$nextTick(() => {
        if (!_this.$refs['imgRef' + index][0].getAttribute('src')) {
          request({
            url: item.url,
            method: 'get',
            responseType: 'blob',
            headers: {
                'token': this.getToken()[' ceis_token']
              }
          }) .then(res => {
            _this.blobToBase64(res).then(result => {
              let imageUrl =  result
              _this.$refs['imgRef' + index][0].setAttribute('src', imageUrl)
            })  
          })
        } 
      })     
    },
    blobToBase64(blob) {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.onload = function (e) {
                resolve(e.target.result);
            }
            reader.readAsDataURL(blob);
            reader.onerror = () => {
              reject(new Error('文件流异常'))
            }
          })
        },
   }
    

此时文件流格式就被转化为base64了,可以兼容任意浏览器了

至此就完成了

传给后台的值仍是fileList,其中保留的是url,在img上动态绑定的是base64格式