html2Canvas实现dom转换为pdf时候,外链地址跨域解决

306 阅读2分钟

代码:

html2Canvas(document.querySelector('.person-info-wrap'), {
    allowTaint: true,
    useCORS: true,//这两个字段只有当图片服务器端设置允许跨域才有效,否则下载的时候也会报跨域
  }).then( (canvas)=> {
    let contentWidth = canvas.width
    let contentHeight = canvas.height
    let pageHeight = contentWidth / 592.28 * 841.89
    let leftHeight = contentHeight
    let position = 5
    let imgWidth = 595.28
    let imgHeight = 592.28 / contentWidth * contentHeight
    let pageData = canvas.toDataURL('image/jpeg', 1.0)
    let PDF = new JsPDF('', 'pt', 'a4')
    if (leftHeight < pageHeight) {
      PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
    } else {
      while (leftHeight > 0) {
        PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
        leftHeight -= pageHeight
        position -= 841.89
        if (leftHeight > 0) {
          PDF.addPage()
        }
      }
    }
    PDF.save(title + '.pdf')
  }
  )

当前场景:person-info-wrap改类上存在一个<img :src="imgUrl" alt="">而imgUrl为图片服务器的地址,不能直接在canvas被支持,会出现跨域问题。因此转换的pdf文件中该外链图片不显示。 假设当图片服务器端某种原因无法设置跨域处理的时候,我的解决的办法: 前提后端提供一个二进制流的返回接口: 后端返回如图示:

  • 返回为图片的二进制流: res-img.png
  • 返回文件的二进制流:

res-other.png 前端代码:

import axios from 'axios'

//address为后端返回的图片服务器地址
getImage(address){
axios({
    method: 'get',
    url: 'http://192.168.60.131:8270/gzjxjy/api/file/download?url='+address,
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        Authorization: sessionStorage.getItem('authorization'),
    },
    responseType: 'blob'//重点,如果设置arraybuffer接收返回的时候经过其他处理,使用blob就可以直接使用下面的URL.createObjectURL来直接转换
}).then((res) => {  
   this.imgUrlwindow.URL.createObjectURL(res)
}).catch((err)=>{
  console.log('-=-=-=-',err)
})
}
}

这样之后,上面的外链图片就会被转换为下面图示的本地路径,所以就不会存在跨域问题了:

blob-img.png

遇到的其他问题

因为返回的是二进制流的形式,而一般的项目都会对请求返回进行请求返回拦截,这样就会存在可能会出现被拦截成错误的时候,因此需要对其放开: 所以会出现请求返回正确而本地会报错,会走axios.catch方法原因:解决方法为针对那个请求特点进行判断:

//  响应拦截
axios.interceptors.response.use((res) => {
  if (res.data.code == 200 || res.data.status_code == 200) {
    return Promise.resolve(res.data)
  } else if(res.data.code == 401) {
    Message.error(res.data.status_desc || 'Error');
    // 跳转到首页 登录失效
    window.location.href = '/login';
    sessionStorage.removeItem("userInfo");
    sessionStorage.removeItem("authorization");
  } else {
    //当返回的为流文件,并且为[object Blob]的时候
    if(res.status ==200 && Object.prototype.toString.call(res.data) == '[object Blob]'){//解决头像html2canvas会出现的问题外联无法下载问题,解决为后台直接返回流会被这个返回拦截器拦截到错误
      return Promise.resolve(res.data)
    }
    Message.error(res.data.status_desc || 'Error');
    return Promise.reject(res.data);
  }
}, (err) => {
  // tryHideFullScreenLoading();
  // Message({ message: err.message, type: 'error' })
  return Promise.reject(err)
})

存在问题:可能这样res.status ==200 && Object.prototype.toString.call(res.data) == '[object Blob]'存在不合理的,这样会导致是blob二进制流都会被放开。