轻松搞定网页截图,html2canvas入门教程
点赞 + 关注 + 收藏 = 学会了
html2canvas 简介
html2canvas 是一个纯前端的 JavaScript 库,能直接在浏览器里把 HTML 元素 “拍” 成 Canvas 图片。不用麻烦后端接口,就能实现网页截图、生成分享海报、保存页面快照等需求。
安装方法
html2canvas 支持两种常见的安装方式,根据你的项目环境选就行:
1. npm /yarn 安装(推荐)
# npm 安装
npm install html2canvas
# yarn 安装
yarn add html2canvas
本文使用 Vite 创建 Vue3 项目,通过 Vue3 的语法来讲解。在其他框架使用 html2canvas 用法也是差不多的。
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js">script>
基础用法
先看一个最简单的例子:点击按钮,把指定的 div 转成 Canvas 并显示在页面上。

随便写点什么,html2canvas 会把它变成图片~
点击截图
<script setup>
import { ref } from 'vue'
import html2canvas from 'html2canvas'
// 获取要截图的 DOM 元素
const captureRef = ref(null)
// 截图函数
const handleCapture = async () => {
// 调用 html2canvas,等待生成 Canvas
const canvas = await html2canvas(captureRef.value)
// 把 Canvas 加到页面上看看效果
document.body.appendChild(canvas)
}
script>这段代码看似简单,但第一个坑也出现了。
此时如果在“截图区”加多一个 h2,结果可能会出乎你所料。

雷猴
随便写点什么,html2canvas 会把它变成图片~
标题的样式没跟着生成出来啊。。。解决方法很简单,不使用浏览器默认样式,给所有标签都加上指定样式。

这是要截图的内容
随便写点什么,html2canvas 会把它变成图片~
点击截图
<script setup>
import { ref } from 'vue'
import html2canvas from 'html2canvas'
// 获取要截图的 DOM 元素
const captureRef = ref(null)
// 截图函数
const handleCapture = async () => {
// 调用 html2canvas,等待生成 Canvas
const canvas = await html2canvas(captureRef.value)
// 把 Canvas 加到页面上看看效果
document.body.appendChild(canvas)
}
script>
常用配置选项
html2canvas 提供了很多配置项,能帮你解决各种场景问题,这里列几个最常用的:
配置项类型默认值说明 scalenumberwindow.devicePixelRatio缩放比例,默认用设备像素比,提高截图清晰度(设为 1 会模糊)。useCORSbooleanfalse是否允许加载跨域图片,设为 true 才能正确显示跨域图片。backgroundColorstring#ffffffCanvas 背景色,设为 null 可以得到透明背景。loggingbooleanfalse是否在控制台打印日志,调试时可以设为 true 看问题。scrollXnumber0截图时的水平滚动偏移,解决页面滚动导致的内容错位。scrollYnumber0截图时的垂直滚动偏移,同上。
如果你要截的元素包含图片,而且这张图片和你的网站存在跨域情况,大概率会出现图片出空白的情况。

这是要截图的内容
随便写点什么,html2canvas 会把它变成图片~
点击截图
<script setup>
import { ref } from 'vue'
import html2canvas from 'html2canvas'
// 获取要截图的 DOM 元素
const captureRef = ref(null)
// 截图函数
const handleCapture = async () => {
// 调用 html2canvas,等待生成 Canvas
const canvas = await html2canvas(captureRef.value)
// 把 Canvas 加到页面上看看效果
document.body.appendChild(canvas)
}
script>
要解决这个问题需要2步操作。
1. 图片服务器配置
Access-Control-Allow-Origin: *(允许跨域)2. html2canvas 配置
useCORS: true
如果想更稳妥一点,还可以给图片标签加 crossorigin="anonymous" 属性。
https://iili.io 这个图床是允许跨域的,所以我们直接在 html2canvas 里配置 useCORS: true 即可。

// 省略部分代码
const canvas = await html2canvas(captureRef.value, {
useCORS: true
})
高级用法:导出并下载图片
生成 Canvas 后,通常需要把它转成图片文件让用户下载,这里用 toDataURL 实现

这是要截图的内容
随便写点什么,html2canvas 会把它变成图片~
点击截图
<script setup>
import { ref } from 'vue'
import html2canvas from 'html2canvas'
// 获取要截图的 DOM 元素
const captureRef = ref(null)
// 截图函数
const handleCapture = async () => {
// 调用 html2canvas,等待生成 Canvas
const canvas = await html2canvas(captureRef.value, { useCORS: true });
// 1. 把 Canvas 转成 PNG 格式的 base64 数据
const imgData = canvas.toDataURL('image/png');
// 2. 创建下载链接
const link = document.createElement('a');
link.download = '我的截图.png'; // 下载的文件名
link.href = imgData;
// 3. 触发点击下载
link.click();
}
script>
常见坑点及避坑指南
html2canvas 虽然好用,但坑也不少。
跨域图片不显示或报错
前面已经提到了,如果截图里有跨域图片(比如图床的图),默认会显示空白。原因是浏览器的同源策略限制,html2canvas 无法直接读取跨域图片的像素。
解决方法:
• 图片服务器配置
Access-Control-Allow-Origin: *(允许跨域)• 给图片标签加
crossorigin="anonymous"属性• html2canvas 配置
useCORS: true
CSS 样式显示异常
部分 CSS 属性(如 transform、box-shadow、复杂渐变、伪元素 ::before/::after)可能渲染不对,甚至完全不显示。
html2canvas 是通过解析 DOM 和 CSS 手动绘制 Canvas 的,不是所有 CSS 都支持。
解决方法:
• 尽量用简单的 CSS 布局,避免太复杂的特效
• 把复杂样式(如渐变、阴影)转成图片代替
• 查看官方文档的 CSS 支持列表,避开不支持的属性
自定义字体渲染失败
用了自定义字体(如 @font-face),截图里却变成了默认字体。
html2canvas 截图时,字体可能还没加载完,就用了默认字体渲染。
解决方法:
• 等待字体加载完成后再截图,用
document.fonts.ready即可
document.getElementById('btn').addEventListener('click', async () => {
// 等待所有字体加载完成
await document.fonts.ready;
const element = document.getElementById('capture');
const canvas = await html2canvas(element);
document.body.appendChild(canvas);
});
滚动条导致截图不全或有滚动条
如果要截图的元素有滚动条,截图会包含滚动条,或者内容被截断。
解决方法:
• 截图前先隐藏滚动条,截图后恢复
const element = document.getElementById('capture');
// 保存原来的 overflow 样式
const originalOverflow = element.style.overflow;
// 隐藏滚动条
element.style.overflow = 'hidden';
const canvas = await html2canvas(element, {
scrollX: 0,
scrollY: 0 // 重置滚动偏移
});
// 恢复原来的样式
element.style.overflow = originalOverflow;
iframe 内容无法捕获
如果页面里有 iframe,html2canvas 无法截图 iframe 里的内容。
同源策略限制,无法直接访问 iframe 内部的 DOM。
解决方法:
• 如果 iframe 和主页面同域,可以手动获取 iframe 里的元素再截图
• 如果跨域,基本无解,建议换其他方案(比如后端截图)
页面元素太多导致性能差
截图区域元素多、图片大时,生成 Canvas 会很慢,甚至浏览器卡顿。
解决方法:
• 适当降低
scale(比如设为 1.5 而不是 2)• 截图前隐藏不必要的元素(比如
display: none)• 只截图需要的部分,不要截整个页面
SVG 元素显示异常
直接截图 SVG 可能会变形、错位,甚至不显示。
解决方法:
• 先把 SVG 转成图片,再插入 DOM 截图。可以用
canvg库辅助转换,或者手动把 SVG 转成 base64 图片
// 简单的 SVG 转图片示例
const svgElement = document.querySelector('svg');
const svgData = new XMLSerializer().serializeToString(svgElement);
const img = new Image();
img.src = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgData)));
// 等图片加载完后,替换原来的 SVG,再截图
img.onload = async () => {
svgElement.parentNode.replaceChild(img, svgElement);
const canvas = await html2canvas(element);
document.body.appendChild(canvas);
};
z-index 层级错乱
截图里的元素层级和实际页面不一样,该在上面的元素跑到下面了。
html2canvas 对 z-index 的解析有时会出问题,尤其是元素没有显式设置 position 时。
解决方法:
• 给需要层级的元素显式设置
position(如relative、absolute)• 调整 DOM 顺序(后面的元素会覆盖前面的),代替
z-index
点赞 + 关注 + 收藏 = 学会了
