背景

        在做前端开发的过程中,做过很多的项目,都会遇到图片预览和展示。一般的图片都是用于页面美化,信息解释说明的作用。但是在接触某些业务场景时,例如用户注册需要上传用户个人身份证照片,办理业务需要上传证明材料图片,这类图片信息属于个人隐私,在网络传输过程中,可能会出现泄露,极大的安全风险。所以对于涉及个人隐私的图片在网络传输过程中有极大的安全要求。

解决方案

      图片上传

        上传图片过程中,传输数据指定为二进制类型,在request请求体,Header上加入token校验。后台可通过token校验,验证上传用户的合法性,同时该token具备时效性,过段时间token会失效,时间间隔可自定义完成。

      图片下载

        图片下载过程中,同样在request请求体,Header上加入token校验。token的校验机制与图片上传相同,前端通过接二进制流后,转化为base64图片格式进行展示。

代码实现 

     前端图片上传处理逻辑

    此处我的实例是图片上传,实际情况上传的文件加判断逻辑。

getFileName(event){
      var file = event.target.files;
      var fileName = file[0].name;
      var arr_index = fileName.lastIndexOf(".");  
      var ext = fileName.substr(arr_index+1).toUpperCase();         //图片上传文件格式校验逻辑
      ext = ext.toLowerCase(); 
      if (ext!='jpg' && ext!='png'){    
          this.$Modal.error({
            title: '温馨提示',
            content: '文件只能上传jpg或者png格式文件。'
          })  
      }else{
        var formData = new FormData();
        formData.append('file',file[0]);
        this.uploadFileMethod(formData);
      }     
    },
    uploadFileMethod(formData){
      let self = this;
      let params={
        fileData:formData
      }
      uploadFileForImage(params).then(res=>{
        if (res.data&&res.data.success) {
         // 上传完成时逻辑
        } 
        self.$store.commit('showLoadingFlag', false)
      })
    }

前端图片查看及下载处理逻辑:

// 图片展示逻辑 
loadImageMethod (imageid) {
      let self = this
      getImagesDetail(imageid).then(res => {
        if (res) {
          var blob = res
          if (blob.size > 0) {
 // 转换为base64,可以直接放入img标签src中
            var reader = new FileReader()
            reader.readAsDataURL(blob)
            reader.onload = function (e) {
              self.imageSrc = e.target.result
            }
          } else {
            self.$Message.error('未找到图片资源')
          }
        }
      }, function (err) {
        self.$Message.error('服务器异常')
      })
    }
    //图片下载
    downloadImage(index){
      let aLink = document.createElement('a');
      aLink.download = this.imageList[index].catelogname+'.jpg';
      aLink.href = this.imageSrc;
      aLink.click();
    }

后端请求api调用实例如下:

import filerequest from '@/libs/api.file.request'
export const getImagesDetail = (imageid) => {
  return filerequest.request({
    url: '/activity/images/' + imageid ,
    method: 'GET'
  })
}

图片上传和下载核心逻辑:

在前端通用公共逻辑的文件夹下,创建文件fileRquest的文件:

import FileRequest from '@/libs/FileRequest'

const filerequest = new FileRequest()
export default filerequest

此处是自己通过promise封装的上传和下载调用的方法:

注:在获取接受文件流的,需要指定返回的类型,即responseType 为 "blob";

import config from '@/config'
const baseUrl = process.env.NODE_ENV === 'development' ? config.baseUrl.dev : config.baseUrl.pro

class FileRequest {
  request (options) {
      if(options.data&&options.method.toLocaleLowerCase() === "post"){
        return new Promise(function(resolve, reject) {
        let xhr = new XMLHttpRequest();
        xhr.open(options.method,baseUrl+options.url)
       //以下为传入token值
        xhr.setRequestHeader("usertoken",'xxxxxx');
        xhr.setRequestHeader("Content-Type", "multipart/form-data");
          xhr.onload = function (res) {
            if (this.status === 200) {
              resolve(this.response);
            }else{
              reject(this.response);
            }
          }
          xhr.send(options.data);    
        })
      }else{
        return new Promise(function(resolve, reject) {
          let xhr = new XMLHttpRequest();
          xhr.open(options.method,baseUrl+options.url)
        xhr.setRequestHeader("usertoken",store.getters.token);
        //注意获取接文件流需要指定,返回类型为blob
          xhr.responseType = "blob";   
          xhr.onload = function (res) {
            if (this.status === 200) {
            resolve(this.response);
            }else{
            reject(this.response);
            }
          }
          xhr.send();    
        })
      }
  }
}
export default FileRequest