跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaScript大前端

前端 html2canvas 使用场景详解

html2canvas 库在 front-end 开发的 9 种核心应用场景,涵盖基础 DOM 转 Base64 图片、跨域图片处理、滚动长列表截图、Vue 及 React 组件集成、隐藏 DOM 生成、批量截图优化、常见报错解决以及 Canvas 转 Blob 上传服务器。包含代码示例与参数配置,帮助开发者实现高质量页面截图功能。

孤勇者发布于 2026/4/5更新于 2026/5/2243 浏览

html2canvas 是前端常用的'DOM 转图片'库,核心是将页面 DOM 节点渲染为 Canvas,再转为图片(Base64 或 Blob)。以下是 9 种核心使用场景的详细教程,包含代码示例、参数配置、问题解决,覆盖日常开发需求。

一、基础使用:将指定 DOM 转为 Base64 图片

适用于简单场景(如生成证书、截图分享),无需复杂配置。

1. 安装与引入
# npm 安装
npm install html2canvas --save
// 模块化项目引入(Vue/React/Angular)
import html2canvas from 'html2canvas';

// 非模块化项目(直接引入 CDN)
// <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/html2canvas.min.js"></script>
2. 核心代码
<!-- 目标 DOM:需要转为图片的容器 -->
<div id="targetDom">
  <h2>基础截图示例</h2>
  <p>这是要转为图片的内容</p>
</div>
<!-- 图片预览容器 -->
<img id="previewImg" />
// 触发截图(如点击按钮后)
document.querySelector('#btn').addEventListener('click', async () => {
  // 1. 获取目标 DOM
  const targetDom = document.getElementById('targetDom');
  
  // 2. 调用 html2canvas 生成 Canvas
   canvas =  (targetDom, {
    : ,              
    : ,         
    : ,        
    :   
  });
  
  
   base64Img = canvas.(, ); 
  
  
  .(). = base64Img;
  
  
   link = .();
  link. = base64Img;
  link. = ;
  link.();
});
const
await
html2canvas
scale
2
// 2 倍缩放,避免图片模糊(关键参数)
useCORS
true
// 允许跨域图片(如网络图片)
logging
false
// 关闭控制台日志
backgroundColor
null
// 保留 DOM 原有背景(默认白色)
// 3. Canvas 转为 Base64 图片(支持 jpeg/png)
const
toDataURL
'image/jpeg'
1.0
// 1.0 表示质量(0-1)
// 4. 预览图片
document
getElementById
'previewImg'
src
// 5. (可选)下载图片
const
document
createElement
'a'
href
download
'基础截图.jpg'
click

二、进阶场景:处理跨域图片

当 DOM 中包含网络图片(如 https://xxx.com/xxx.jpg),易出现'图片空白'问题,需配置跨域参数。

关键配置
  1. 前端配置:useCORS: true + allowTaint: true(允许跨域图片污染 Canvas);
  2. 后端配置:图片服务器需返回 Access-Control-Allow-Origin: *(或当前域名),否则跨域图片仍会空白。
完整代码
const canvas = await html2canvas(targetDom, {
  scale: 2,
  useCORS: true,          // 允许加载跨域图片
  allowTaint: true,       // 允许 Canvas 被跨域图片污染(否则图片会被过滤)
  logging: false,         // (可选)处理跨域图片加载失败的情况
  onclone: (clonedDoc) => {
    // clonedDoc 是 DOM 克隆体,可在此修改图片地址
    const imgs = clonedDoc.querySelectorAll('img');
    imgs.forEach(img => {
      // 替换图片为同源地址(若后端未配置 CORS 时的备选方案)
      if (img.src.includes('跨域域名')) {
        img.src = img.src.replace('跨域域名', '同源代理域名');
      }
    });
  }
});

三、复杂场景:固定宽高 + 滚动内容截图

适用于'长列表截图'(如表格、聊天记录),需固定截图宽高,同时包含滚动区域的所有内容。

核心思路
  1. 先保存目标 DOM 的原始样式(overflow/height);
  2. 临时修改为 overflow: visible + 自适应高度(确保所有内容展开);
  3. 截图完成后恢复原始样式。
完整代码
async function captureScrollContent() {
  const targetDom = document.getElementById('targetDom');
  
  // 1. 保存原始样式
  const originalStyle = {
    overflow: targetDom.style.overflow,
    height: targetDom.style.height
  };
  
  try {
    // 2. 临时修改样式:展开所有滚动内容
    targetDom.style.overflow = 'visible';
    targetDom.style.height = 'auto'; // 自适应高度,显示所有内容
    
    // 3. 截图(固定宽高,避免内容变形)
    const canvas = await html2canvas(targetDom, {
      scale: 2,
      useCORS: true,
      logging: false,
      windowWidth: targetDom.offsetWidth,   // 固定截图宽度
      windowHeight: targetDom.offsetHeight  // 固定截图高度(此时已包含所有内容)
    });
    
    // 4. 转为图片并下载
    const base64Img = canvas.toDataURL('image/png', 1.0);
    const link = document.createElement('a');
    link.href = base64Img;
    link.download = '长列表截图.png';
    link.click();
  } finally {
    // 5. 恢复原始样式(无论成功失败都要恢复)
    targetDom.style.overflow = originalStyle.overflow;
    targetDom.style.height = originalStyle.height;
  }
}
// 调用 captureScrollContent();

四、Vue 项目:组件内 DOM 截图(含响应式数据)

Vue 中需注意'DOM 渲染时机'—— 确保数据更新后(如接口请求完成)再截图,避免内容空白。

核心注意点
  1. 用 this.$nextTick() 确保 DOM 已更新;
  2. 若用 v-for 渲染列表,需等待列表渲染完成后再截图。
完整代码(Vue 3 示例)
<template>
  <div>
    <!-- 目标 DOM:包含响应式数据 -->
    <div ref="certDom" class="cert-container">
      <h2>{{ userName }} 的证书</h2>
      <p>项目:{{ projectName }}</p>
      <p>时间:{{ date }}</p>
    </div>
    <button @click="generateCert">生成证书</button>
    <img :src="previewImg" alt="证书预览" />
  </div>
</template>

<script setup>
import { ref, nextTick } from 'vue';
import html2canvas from 'html2canvas';

// 响应式数据
const userName = ref('');
const projectName = ref('');
const date = ref('2025-01-01');
const previewImg = ref('');
const certDom = ref(null); // 目标 DOM 引用

// 接口请求:获取用户数据
const fetchUserInfo = async () => {
  const res = await fetch('/api/user');
  const data = await res.json();
  userName.value = data.userName;
  projectName.value = data.projectName;
};

// 生成证书(截图)
const generateCert = async () => {
  // 1. 先获取数据,确保 DOM 已更新
  await fetchUserInfo();
  
  // 2. 等待 Vue DOM 渲染完成
  await nextTick();
  
  // 3. 截图(certDom.value 是目标 DOM)
  const canvas = await html2canvas(certDom.value, {
    scale: 2,
    useCORS: true,
    backgroundColor: '#fff'
  });
  
  // 4. 预览并下载
  previewImg.value = canvas.toDataURL('image/jpeg', 1.0);
  const link = document.createElement('a');
  link.href = previewImg.value;
  link.download = `${userName.value}的证书.jpg`;
  link.click();
};
</script>

<style scoped>
.cert-container {
  width: 500px;
  height: 700px;
  background: url('@/assets/cert-bg.jpg') no-repeat center;
  background-size: 100% 100%;
  padding: 50px;
  box-sizing: border-box;
}
</style>

五、React 项目:函数组件截图(含 Hooks)

React 中需用 useRef 获取 DOM 节点,用 useEffect 处理异步渲染时机。

完整代码(React 18 示例)
import { useRef, useState } from 'react';
import html2canvas from 'html2canvas';

const ScreenshotComponent = () => {
  // 1. 获取目标 DOM 引用
  const targetRef = useRef(null);
  
  // 2. 预览图片状态
  const [previewImg, setPreviewImg] = useState('');
  
  // 截图函数
  const captureDom = async () => {
    if (!targetRef.current) return;
    
    // 3. 调用 html2canvas
    const canvas = await html2canvas(targetRef.current, {
      scale: 2,
      useCORS: true,
      logging: false
    });
    
    // 4. 转为图片
    const base64 = canvas.toDataURL('image/png', 1.0);
    setPreviewImg(base64);
    
    // 5. 下载图片
    const link = document.createElement('a');
    link.href = base64;
    link.download = 'react 截图.png';
    link.click();
  };
  
  return (
    <div style={{ padding: 20 }}>
      {/* 目标 DOM:用 ref 绑定 */}
      <div ref={targetRef} style={{ width: 400, height: 300, background: '#e8f4f8', padding: 20 }}>
        <h3>React 截图示例</h3>
        <p>当前时间:{new Date().toLocaleString()}</p>
      </div>
      <button onClick={captureDom} style={{ margin: 20 }}>生成截图</button>
      {previewImg && <img src={previewImg} alt="预览" style={{ maxWidth: '100%' }} />}
    </div>
  );
};

export default ScreenshotComponent;

六、特殊场景:隐藏 DOM 截图(不显示在页面)

适用于'后台生成图片'(如生成后直接下载,无需在页面显示 DOM),需临时将 DOM 渲染到页面外。

核心思路
  1. 目标 DOM 初始样式设为 position: absolute; left: -9999px; top: -9999px;(隐藏在视口外);
  2. 截图完成后可删除该 DOM(可选)。
完整代码
<!-- 隐藏的目标 DOM:在视口外渲染 -->
<div id="hiddenDom">
  <h2>隐藏 DOM 生成的图片</h2>
  <p>用户:张三</p>
  <p>等级:VIP</p>
</div>
<button id="generateBtn">生成隐藏图片</button>
document.getElementById('generateBtn').addEventListener('click', async () => {
  const hiddenDom = document.getElementById('hiddenDom');
  
  // 截图(与正常 DOM 一致)
  const canvas = await html2canvas(hiddenDom, {
    scale: 2,
    useCORS: true,
    logging: false
  });
  
  // 下载图片
  const base64 = canvas.toDataURL('image/jpeg', 1.0);
  const link = document.createElement('a');
  link.href = base64;
  link.download = '隐藏 DOM 图片.jpg';
  link.click();
  
  // (可选)截图后删除隐藏 DOM
  // hiddenDom.remove();
});

七、性能优化:批量截图 + 避免重复渲染

当需要批量生成图片(如多条数据生成证书),需控制截图顺序,避免同时渲染导致浏览器卡顿。

核心思路
  1. 用 async/await 按顺序截图(一条完成后再截下一条);
  2. 截图前判断是否已生成,避免重复操作。
完整代码
// 批量数据(如多条证书信息)
const certList = [
  { id: 1, userName: '张三', project: '前端开发' },
  { id: 2, userName: '李四', project: '后端开发' },
  { id: 3, userName: '王五', project: 'UI 设计' }
];

// 批量截图函数
async function batchCapture() {
  for (const cert of certList) {
    // 1. 动态创建目标 DOM(每条数据一个 DOM)
    const tempDom = document.createElement('div');
    tempDom.style.width = '500px';
    tempDom.style.height = '700px';
    tempDom.style.background = '#fff';
    tempDom.style.padding = '50px';
    tempDom.style.position = 'absolute';
    tempDom.style.left = '-9999px'; // 隐藏在视口外
    tempDom.innerHTML = `
      <h2>${cert.userName} 的证书</h2>
      <p>项目:${cert.project}</p>
      <p>日期:2025-01-01</p>
    `;
    document.body.appendChild(tempDom);
    
    try {
      // 2. 截图(按顺序执行)
      const canvas = await html2canvas(tempDom, {
        scale: 2,
        useCORS: true,
        logging: false
      });
      
      // 3. 下载图片
      const base64 = canvas.toDataURL('image/jpeg', 1.0);
      const link = document.createElement('a');
      link.href = base64;
      link.download = `${cert.userName}的证书.jpg`;
      link.click();
    } finally {
      // 4. 移除临时 DOM(避免内存占用)
      document.body.removeChild(tempDom);
      
      // (可选)延迟 500ms,避免浏览器卡顿
      await new Promise(resolve => setTimeout(resolve, 500));
    }
  }
}
// 调用批量截图
batchCapture();

八、问题解决:常见报错与优化方案

1. 图片模糊
  • 原因:Canvas 默认缩放为 1,屏幕 DPI 过高(如 Retina 屏)导致模糊;
  • 解决:设置 scale: 2 或 scale: window.devicePixelRatio(自适应屏幕 DPI)。
const canvas = await html2canvas(targetDom, {
  scale: window.devicePixelRatio, // 自适应屏幕缩放
  useCORS: true
});
2. 跨域图片空白
  • 原因:图片服务器未配置 CORS,或未开启 useCORS: true;
  • 解决:
    1. 后端添加 Access-Control-Allow-Origin 响应头;
    2. 前端配置 useCORS: true + allowTaint: true;
    3. 备选方案:用同源代理服务器转发图片(如 Nginx 代理)。
3. DOM 内容未完全渲染(如接口数据空白)
  • 原因:截图时机过早,DOM 尚未更新(如接口请求未完成);
  • 解决:
    • Vue:用 this.$nextTick() 等待 DOM 渲染;
    • React:用 useEffect 或 await 等待数据加载;
    • 原生 JS:在接口 then 回调中执行截图。
4. 大 DOM 截图卡顿
  • 原因:DOM 节点过多(如长列表、复杂表格),渲染耗时;
  • 解决:
    1. 简化 DOM(移除截图无关的节点,如隐藏按钮、多余注释);
    2. 分批截图(避免一次性渲染大量节点);
    3. 关闭日志:logging: false(减少控制台输出耗时)。

九、高级场景:Canvas 转 Blob 上传服务器

当需要将生成的图片上传到后端(而非本地下载),需将 Canvas 转为 Blob 格式(比 Base64 更节省带宽)。

完整代码
async function captureAndUpload() {
  const targetDom = document.getElementById('targetDom');
  const canvas = await html2canvas(targetDom, {
    scale: 2,
    useCORS: true,
    logging: false
  });
  
  // 1. Canvas 转为 Blob(支持指定格式和质量)
  canvas.toBlob(async (blob) => {
    // 2. 构建 FormData(用于上传)
    const formData = new FormData();
    formData.append('image', blob, '上传图片.jpg'); // 第三个参数是文件名
    formData.append('userId', '123');               // 其他参数(如用户 ID)
    
    // 3. 上传到服务器
    try {
      const res = await fetch('/api/upload-image', {
        method: 'POST',
        body: formData, // 注意:FormData 上传无需设置 Content-Type,浏览器会自动处理
      });
      const data = await res.json();
      if (data.success) {
        alert('图片上传成功!');
        console.log('图片地址:', data.imageUrl);
      }
    } catch (err) {
      console.error('上传失败:', err);
    }
  }, 'image/jpeg', 0.8); // 0.8 表示图片质量(0-1,值越高质量越好)
}
// 调用 captureAndUpload();

目录

  1. 一、基础使用:将指定 DOM 转为 Base64 图片
  2. 1. 安装与引入
  3. npm 安装
  4. 2. 核心代码
  5. 二、进阶场景:处理跨域图片
  6. 关键配置
  7. 完整代码
  8. 三、复杂场景:固定宽高 + 滚动内容截图
  9. 核心思路
  10. 完整代码
  11. 四、Vue 项目:组件内 DOM 截图(含响应式数据)
  12. 核心注意点
  13. 完整代码(Vue 3 示例)
  14. 五、React 项目:函数组件截图(含 Hooks)
  15. 完整代码(React 18 示例)
  16. 六、特殊场景:隐藏 DOM 截图(不显示在页面)
  17. 核心思路
  18. 完整代码
  19. 七、性能优化:批量截图 + 避免重复渲染
  20. 核心思路
  21. 完整代码
  22. 八、问题解决:常见报错与优化方案
  23. 1. 图片模糊
  24. 2. 跨域图片空白
  25. 3. DOM 内容未完全渲染(如接口数据空白)
  26. 4. 大 DOM 截图卡顿
  27. 九、高级场景:Canvas 转 Blob 上传服务器
  28. 完整代码
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • LLM 大模型入门教程:训练、微调与推理实战指南
  • OpenClaw Web 控制台使用全解析——可视化配置与监控
  • AR Core 与 CameraX 融合:测量应用原理与实现
  • Qwen-Image-2512 技术亮点解析与 ComfyUI 部署实战
  • 前端使用 Document Picture-in-Picture API 实现视频小窗同步控制
  • MyBatis 动态 SQL 语句常用元素
  • ESP32-S3 部署 MimicLaw 结合 DeepSeek 与飞书机器人实现对话
  • DeepSeek 系列模型版本演进与核心特性对比
  • 使用码云 Gitee 登录 Ruoyi-Vue-Pro 配置指南
  • 2025 无人机四大顶会精选:16 篇前沿论文解析(IROS/ICRA/RSS/CoRL)
  • C++ STL 哈希表原理与模拟实现
  • OpenClaw 本地 AI 智能体:部署与实战指南
  • Flutter与Web混合开发实践
  • Python 数据可视化绘图基础与实战指南
  • PyTorch 深度学习框架核心特性与入门
  • Whisper 语音识别技术突破:大型模型高速优化版解析
  • Windows 本地部署 OpenClaw 对接飞书机器人实战
  • SORT 追踪算法详解与 C# 实现案例
  • 智能梯控系统设计方案:跨品牌群控与 AI 调度架构解析
  • Flutter 集成 Firebase 后端配置与前后端闭环实战

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online