首先说明一下,使用跨域图片绘制会污染canvas画布,导致无法导出canvas数据,转化成图片,这是canvas的特点,不关html2canvas的事,只是此处需求是使用这个库将html转化为图片,故在标题中标上了html2canvas, 标题提得不恰当,有更合适的可以指出,请不要上来就喷
背景与需求
将某段html转化为图片并可下载到本地。
使用方案
通过html2canvas先将html转化为canvas,再通过canvas.toDataURL
将canvas转化为图片
遇到的问题
绘图元素中使用的图片存放在阿里云,因此存在非同源CORS问题,图片可以绘制(allowTaint: true
), 但这样的话,画布被污染,就无法导出canvas的数据转化为图片了
尝试过的方案
方案:foreignObjectRendering: true
结果:图片无法显示,绘图错乱
方案:组合使用allowTaint, useCORS, foreignObjectRendering, onclone
结果:未达效果
方案:图片存放的服务器设置允许跨域(后端同事很确定已经设置了允许跨域访问),转化canvas时设置(allowTaint: false, useCORS: true
)
结果:不知何故,仍提示图片跨域,不允许访问 Access to image at 'xxx' from origin 'xxx' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
方案:将图片转化为base64格式后,再进行绘图,这样就不会污染画布了
方法:通过xhr
请求,设置其responseType为'blob',获得数据后,通过FileReader
的readAsDataURL(blob)
转化为base64格式
问题:xhr请求数据时,就被CORS挡在门外了
方案:设置image crossorigin属性
结果:未达效果
相关的方案链接:
convert all images to base64 after onclone
官方方案html2canvas: proxy
官方指导-proxy
关于Proxy使用的issue
官方指导的nodejs示例
疑惑
我看了官方指导的nodejs示例源码及使用示例,粗略理解为:它将图片转化为base64格式,结合使用设置(proxy: theProxyURL
), 绘制到跨域图片时,会去访问theProxyURL下转化好格式的图片,由此解决了画布污染问题。
我感到有些疑惑,这样的转化方式,就不会遇到CORS问题了吗?使用proxy
可以解决这个问题的关键究竟在哪里?
我的这个理解是否正确?若用此方式,是否单独部署proxy相关代码,将proxy设置为其地址即可?
mark:
由于canvas画布污染的原因是图片跨域,使用base64格式的图片,即可解决问题,因此,此处未尝试proxy方案(要单独部署),而采取了其他方案:让后端返回base64格式的图片。
相关后续:
需求:用户可主动下载html转化的图片
方法:将
base64
转化为blob
, 再通过createObjectURL
将blob
`转化为url
。设置a标签
`href与
download`属性,达到点击该a标签将图片下载到本地的目的。附主要方法: