代码:
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文件中该外链图片不显示。
假设当图片服务器端某种原因无法设置跨域处理的时候,我的解决的办法:
前提后端提供一个二进制流的返回接口:
后端返回如图示:
- 返回为图片的二进制流:
- 返回文件的二进制流:
前端代码:
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.imgUrl= window.URL.createObjectURL(res)
}).catch((err)=>{
console.log('-=-=-=-',err)
})
}
}
这样之后,上面的外链图片就会被转换为下面图示的本地路径,所以就不会存在跨域问题了:
遇到的其他问题
因为返回的是二进制流的形式,而一般的项目都会对请求返回进行请求返回拦截,这样就会存在可能会出现被拦截成错误的时候,因此需要对其放开: 所以会出现请求返回正确而本地会报错,会走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二进制流都会被放开。