总结一下使用html2canvas截图时遇到的问题

近期做需求,有个页面截图下载到本地的功能,这里记录一下使用html2canvas时遇到的问题,简单搭建了一个demo项目(项目地址),用来调试当时遇到的问题。 具体问题如下:

  1. 图片跨域问题
  2. 图片清晰度问题
  3. 图片样式缺失问题
  4. 长图截取不全问题

使用

  1. 安装

官网地址: html2canvas.hertzen.com/

js 复制代码
npm install --save html2canvas
  1. 使用

html2canvas接收两个参数,分别是截取的目标dom元素和配置项,配置项非必传。调用html2canvas方法后,会返回一个绘制好的canvas对象,再通过调用canvas对象的toDataURL方法可以转换成一个图片。

js 复制代码
// 具体代码如下:
const canvas = await html2canvas(document.body, options); // options为对应的配置项
const code = canvas.toDataURL(); // 转换为Base64编码的字符串
const aLink = document.createElement('a'); // 创建a标签自动下载
aLink.download = '下载图片';
aLink.href = code;
aLink.click();

遇到的问题

1. 跨域问题

html2canvas配置项中自带了两个跟跨域相关的配置字段,分别是allowTaintuseCORS

1、allowTaint

由于html2canvas受浏览器同源策略的限制,使用非同源的图片会taint(污染)画布,因此默认allowTaint: false,不允许污染画布,同时图片也不能画在画布上。

在配置项中设置allowTaint: true,虽然会污染画布,但可以将跨域的图片渲染到画布上了。

js 复制代码
const canvas = await html2canvas(element, { allowTaint: true });

不过我不太推荐这种方式,因为它会导致另外一个问题,被污染的画布因为同源策略而存在安全问题 ,导致调用html2canvas后返回的canvas对象中toDataUrl、getImageData等方法会报错,从而没办法将canvas画布信息转换成base64格式的字符串了,这不符合我的预期。 所以我将这个配置项pass掉,不用allowTaint,而是使用useCORS。

  • 使用allowTaint属性后,报错如下:

2、useCORS

在配置项中设置useCORS:true,可以解决跨域问题,原理相同。

js 复制代码
const canvas = await html2canvas(element, { useCORS: true });

图片我用百度的图标当做网络图片,效果图如下:

  • 未设置useCORS
  • 设置useCORS

注意: allowTaintuseCORS不要同时使用,如果二者同时设置为true,仍然会认为画布已被污染而不可用。

2. 图片清晰度问题

通过配置项将scale属性对应的值调整大一点即可,我项目中设置的是4, 在html2canvasscale默认值为浏览器设备像素比

js 复制代码
const canvas = await html2canvas(element, { scale: 4 });

未设置scale和设置scale下载图片到本地后,通过下面这张图可以明显看出来,设置了scale的图片大小要比没有设置的大很多。

下面两张图是通过调整scale对应值的大小,图片的清晰度对比会更加明显一些。

  • 设置scale: 0.8
  • 设置scale: 4

3. 图片样式缺失问题

此问题的原因在于html2canvas有一些css样式是不支持的,导致截取出来的图片有部分样式缺失。因此写页面的时候只要自己注意一下就好了。

官方文档上面也有说明支持哪些css属性,不支持哪些css属性。具体详情可以点击传送门

下面这些css属性是当前不支持的:

4. 长图截取不全问题

遇到这个问题的时候,当时查看官方文档没有找到对应的解决方案,后来自己调试样式,发现设置截图元素的高度就可以完美解决了。

  • 解决方案: 给要截图的元素设置height:fit-content

效果图:

注意:fit-content有兼容行问题,使用的时候需要注意该属性是否符合你的目标浏览器的兼容性。

给截图元素不设置高度或者设置height: auto发现都不起作用,后来尝试使用fit-content这个相对较新的属性后,可以完美解决高度问题。

  • 扩展知识

height: fit-content用于根据元素内容的大小来自动调整元素的高度。它允许你根据内容动态地设置元素的高度,而不是使用固定的像素值或百分比。(这段话来自chatGPT)

另外fit-content可以和min-heightmax-height搭配使用。

  1. min-height搭配使用:当内容实际高度小于指定的最小高度时,元素的高度为min-height指定的高度,否则为元素的实际高度。。
  2. max-height搭配使用:当内容高度大于指定的最大高度时,元素的高度为max-height指定的高度,否则为元素的实际高度。

以上是我在做这个功能时遇到的问题,文中若有不对的地方欢迎各位掘友纠正~。

参考文章

  1. html2canvas.hertzen.com/configurati...
  2. blog.fuwenhao.com/post/351.ht...
相关推荐
小堂子这厢有礼了31 分钟前
Chet.QuartzNet.UI v2.3.0 大更新!表格重构 + 系统配置 + 分析页全面升级!
前端·后端·ui·重构·c#·vue
触底反弹36 分钟前
⚡ Promise.all 性能优化:让 Agent 的工具调用飞起来
javascript·人工智能·后端
程序员爱钓鱼42 分钟前
Rust 控制流 if 详解:条件判断与 if 表达式
前端·后端·rust
心中有国也有家1 小时前
AtomGit Flutter 鸿蒙客户端:错误处理与优雅降级策略
android·javascript·flutter·华为·harmonyos
Listen·Rain1 小时前
Vue3中computed详解
前端·javascript·vue.js
kyle~2 小时前
Swagger ---基于 描述文件 生成 交互式API文档 的工具
前端·后端·规格说明书·说明文档
meilindehuzi_a9 小时前
从零理解并实现 RAG:用 LangChain.js 构建语义检索问答系统
开发语言·javascript·langchain
世界哪有真情10 小时前
拿人类意识卡 AI?等于用 bug 验收正式产品
前端·人工智能·后端
鱼樱前端10 小时前
别再自己拼凑了!这款 Vue 3.5+ 严肃产品级组件库,把 AI 对话、工作流和复杂数据全包了!
javascript·vue.js·github
Listen·Rain11 小时前
Vue3:setup详解
前端·javascript·vue.js