使用
html2canvas
将页面转换成图片的采坑记录
"html2canvas":"^1.4.1","@tarojs/taro":"3.4.0-beta.0"
问题:
1. 生成的图片很模糊
2. 生成的图片是空白
3. 生成的图片不完整
截图前是这样
截图后这样
截图后的图片图片缺省了一部分
解决方案
问题1: 生成的图片很模糊(图片跨域)
方法一: 将canvas放大n倍再作图;
移动端的话,根据移动设备的
devicePixelRatio
(
devicePixelRatio
返回当前显示设备的物理像素分辨率与CSS 像素分辨率之比)决定缩放比例;也可以默认放大两倍转换
**方法二: 使用
<img>
来实现
background-image
的效果**
只有作为
background-image
的背景图会模糊,而
<img>
图片标签是没有这个问题的。
问题2: 生成的图片是空白(图片跨域)
首先确定转换后的canvas的宽高是否正确,如果不正确,就需要给html2canvas传递宽高参数 !!!
没有宽高问题,然后再细细排查发现,在使用 转换的时候图片有跨域问题,导致转换失败,所以转换成了空白图片(大概率都是这个原因);将图片去掉就可以正常转换页面的
解决方案:
方案一:
后端需要在服务器IIS上的HTTP响应标头设置,最简单粗暴的方法就是全部设置成*,不过这样安全性也低,自己可以根据自己需求设置
access-control-allow-credentials:true
Access-Control-Allow-Headers:*
access-control-allow-origin:*
方案二:
在要生成canvas的DOM中的每一个img标签上设置
crossorigin="anonymous"
属性,并且给资源地址加上固定的随机数(避免缓存)
- 给html2anvas添加
useCORS:true
属性- 给要生成canvas的DOM中的每一个img标签上设置
crossorigin="anonymous"
属性- 确保你的图片CDN服务器支持CORS访问,也就是会返回
Access-Control-Allow-Origin
等响应头
在Taro中给img加上该属性之后没生效,因为
在taro中节点被把包裹了一层
taro-image-core
节点导致img属性并没有设置到
img
上(所有在
taro
上该方法不适用)
方案三:
使用html2canvas提供的跨域解决方案
allowTaint: true
和
useCORS: true
都是解决跨域问题的方式,不同的是使用
allowTaint
会对
canvas
造成污染,导致无法使用
canvas.toDataURL
方法;所以这里就给
html2canvas
添加
useCORS: true
,试了一下还是跨域 -.-
方案四
修改
html2canvas
的源码(最终解决方案)
核心思想也就是使用方法二,修改
html2canvas
源码:
1.给
html2canvas
添加
useCORS: true
参数
2. 设置img.crossOrigin = 'anonymous'
(img.crossOrigin = ""和img.crossOrigin = 'anonymous’是等价的)
3.给资源地址添加时间戳数/一个固定的字符串,避免读取到浏览器缓存数据,推荐后者
设置好红框里的内容之后就可以成功的转换了;也没有跨域的错了
由于项目限制,我的图片是不支持CORS访问的,所以选择了方案四解决问题
问题3: 生成的图片不完整
截图不完整是因为我将该图片进行了旋转,解决方案就是:
第一步: 给该图片元素添加一个正方形的父元素
给足空间,保证该图片元素在旋转都在这个容器内
第二步: 一般情况步骤一就可以解决问题了,但我在设置了第一步之后图片还是不完整
经排查发现子元素图片有设置
overflow: hidden
;(因为taro在img节点外包裹了一层 taro-image-core节点 小程序),需要将
overflow: hidden
改成
overflow: visible
问题就解决了
Taro h5代码:
let node = document.querySelector('#html2canvas-dom');html2canvas(element,{useCORS:true,scale: window.devicePixelRatio <3? window.devicePixelRatio :2,width: node?.clientWidth || canvasOption.width,height: node?.clientHeight || canvasOption.height
}).then(canvas=>{// imgUrl 是图片的 base64格式const imgurl = canvas.toDataURL('image/png');
Taro.uploadFile({url:'***',filePath: imgurl,name:'file',header:{'X-Auth-Token':'****'},formData:{method:'POST',fileType:'png'},success:res=>{// ...}});});
参考
html2canvas 采坑记录
html2canvas跨域
html2canvas截图如何解决跨域
dom从旋转html2canvas截取图片
版权归原作者 爱倒腾 所有, 如有侵权,请联系我们删除。