html2canvas,借助canvas由html生成图片并下载
发布于 作者:苏南大叔 来源:程序如此灵动~
需求是通过网页代码,对当前网页进行“截图”,解决方案是html2canvas
。能产生类似截图的效果,但是并不是传统意义上的截图。并没有使用到任何的非网页技术,原理上是在将一个dom
容器渲染到canvas
画布,然后通过画布的内容转化为base64
编码,最终作为图片的内容,“下载”到客户端。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。本文测试环境:win10
,chrome@132.0.6834.160
,html2canvas@1.4.1
。要求不高的话,这个html2canvas
的方案,还是不错的。要求高的话,就弃坑吧。毕竟仅仅是个模拟重绘,细节上还是和真正的截图存在细微差异可能性的。
html2canvas 官网
html2canvas
官网如下:
官方文档:
script引入
引入这个html2canvas
,现在也得分情况讨论。
常规标签引入
官方的html2canvas.min.js
地址:
在npm
安装的html2canvas
下,dist
目录里面,也存在html2canvas.min.js
文件。
打包引入
或者使用webpack
/rollup
等等打包工具,对下面的代码进行打包。除非本来项目就是个这种打包的项目结构,否则相对而言就费事了。
import html2canvas from 'html2canvas';
官网例子(暗示全能)
<script src="js/html2canvas.min.js"></script>
<div
id="capture"
style="padding: 5px; background: #f5da55; margin-bottom: 3px">
<h4 style="color: #000">Hello world!</h4>
</div>
<script>
html2canvas(document.querySelector("#capture")).then((canvas) => {
document.body.appendChild(canvas);
});
</script>
跨域例子(实际非全能)
这里存在着认知之外的跨域问题,
- 截图区域引入外部
css
或者img
的话,不能显示出来,这个妥妥的出人意料啊。 iframe
非同源内容,是妥妥的无法显示的。这个就不是html2canvas
能解决的问题。
<div id="capture" style="background-color: #f0f0f0; width: 160px; float: left">
<img src="https://cdn.deepseek.com/logo.png" style="width: 160px" /><br />
<img src="https://cdn-avatars.hf-mirror.com/v1/production/uploads/6538815d1bdb3c40db94fbfa/xMBly9PUMphrFVMxLX4kq.png" style="width: 160px"/>
</div>
<script>
function getScreenshot() {
html2canvas(document.querySelector("#capture")).then((canvas) => {
document.body.appendChild(canvas);
});
}
function getScreenshot2() {
html2canvas(document.querySelector("#capture"), {
useCORS: true, // 允许跨域,本地允许,还得远程服务器同意呢
}).then((canvas) => {
document.body.appendChild(canvas);
});
}
function getScreenshot3() {
html2canvas(document.getElementById("capture"), {
useCORS: true, // 允许跨域,本地允许,还得远程服务器同意呢
}).then((canvas) => {
const aTag = document.createElement("a");
aTag.href = canvas.toDataURL();
aTag.download = "screenshot.png";
aTag.click();
URL.revokeObjectURL(aTag.href);
});
}
</script>
在这个例子里面,html2canvas
使用useCORS: true
来解决跨域问题。然而,本地canvas
允许跨域了。还需要服务器端也同意这个跨域。一共引入了两个deepseek
的logo
图片:
- 第一个图片,服务器端并没有跨域允许,无法被截取到。
- 第二个图片,服务器端设置了跨域允许,在本地
canvas
也同意跨域后,就可以被截取到了。
结语
html2canvas
的原理是重绘,所以会引起资源的多次请求。对于跨域的情况,还会再额外多一次请求。而且对于iframe
的情况,是原生不支持的。对于一些特殊的css
属性,也是无法在canvas
上绘制的(见官方文档)。所以,对于这些方面要求比较严格的需求里面,请不要使用此方案。
更多苏南大叔的html5
的精彩文章,请点击:


