前端实现页面截图及截图内容包含跨域图片时的处理

项目中遇到需要实现指定位置的截图,采取使用依赖 html2canvas 实现。 参考:html2canvas.hertzen.com/

一、实现步骤:

1、下载依赖或者使用官方js文件链接,本文使用的js链接; 2、代码 style

css 复制代码
.screen-box {
  padding: 20px;
  background-color: #f5f5f5;
}

html

xml 复制代码
<div id="screen-box" class="screen-box">
  <h1>这是一个需要截图的区域</h1>
</div>
<button onclick="screenShot()">点击截图</button>

script

xml 复制代码
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></srcipt>
ini 复制代码
<script>
function screenShot() {
  const element = document.getElementById('screen-box');
  html2canvas(element).then(canvas => {
    const img = canvas.toDataURL('image/png');
    downloadImage(img);
  })
}

function downloadImage(imgUrl, fileName = 'image.png') {
  // 1. 创建a标签
  const link = document.createElement('a');
  // 2. 设置下载属性(指定文件名)
  link.download = fileName;
  // 3. 设置图片地址为a标签的href
  link.href = imgUrl;
  // 4. 隐藏a标签(可选,避免页面渲染)
  // link.style.display = 'none';
  // 5. 将a标签添加到DOM中(部分浏览器需要)
  document.body.appendChild(link);
  // 6. 触发点击事件下载
  link.click();
  // 7. 下载后移除a标签(清理DOM)
  document.body.removeChild(link);
}

二、易错:

1、当 html 中包含有同源图片时,此代码可下载的图片文件中包含html的图片; 2、当 html 中包含跨域图片时,此代码下载的图片文件会中不会显示html包含的文件。 例如,当需截图的代码片段中含有由第三方引入的图片地址: html:

ini 复制代码
<div id="screen-box" class="screen-box">
  <h1>这是一个需要截图的区域</h1>
  <img src="https://gips3.baidu.com/it/u=1821127123,1149655687&fm=3028&app=3028&f=JPEG&fmt=auto?w=720&h=1280"
      height="300px" title="截图区图片" alt="图片" />
</div>
<button onclick="screenShot()">点击截图</button>

截图:

原因:

这是由于 canvas 受限于 CORS 策略, 会存在跨域问题, 虽然可以使用图像, 但是绘制到画布上会污染画布, 一旦一个画布被污染, 就无法提取画布的数据。比如无法使用画布 toBlod() , toDataURL() 或者 getImageData() 方法。

解决办法:

增加代码:

javascript 复制代码
// 将文件读入到 blob 文件对象, 然后使用 URL.createObjectURL 转换成 src 可用的地址
async function toBlob() {
  const domUrl = document.getElementsByTagName('img')[0];
  const response = await fetch(domUrl.src, { mode: 'cors' });
  if (!response.ok) throw new Error('图片请求失败');
  const blob = await response.blob();
  const blobUrl = URL.createObjectURL(blob);
  domUrl.setAttribute('src', blobUrl);
}

修改 screenShot 函数:

csharp 复制代码
async function screenShot() {
  await toBlob();
  ...
}

修改代码后,截图如下:

三、本地地址的图片(地址为"file://"开头)不支持此方法

解决办法:

可将图片转码后赋值img标签的src属性再进行操作。

博客园:www.cnblogs.com/wttt123/p/1...

以上。

相关推荐
会跑的葫芦怪3 小时前
若依Vue 项目多子路径配置
前端·javascript·vue.js
xiaoqi9224 小时前
React Native鸿蒙跨平台如何进行狗狗领养中心,实现基于唯一标识的事件透传方式是移动端列表开发的通用规范
javascript·react native·react.js·ecmascript·harmonyos
jin1233224 小时前
React Native鸿蒙跨平台剧本杀组队消息与快捷入口组件,包含消息列表展示、快捷入口管理、快捷操作触发和消息详情预览四大核心功能
javascript·react native·react.js·ecmascript·harmonyos
烬头88216 小时前
React Native鸿蒙跨平台实现二维码联系人APP(QRCodeContactApp)
javascript·react native·react.js·ecmascript·harmonyos
pas1366 小时前
40-mini-vue 实现三种联合类型
前端·javascript·vue.js
2601_949833396 小时前
flutter_for_openharmony口腔护理app实战+预约管理实现
android·javascript·flutter
军军君017 小时前
Three.js基础功能学习十三:太阳系实例上
前端·javascript·vue.js·学习·3d·前端框架·three
xiaoqi9228 小时前
React Native鸿蒙跨平台如何实现分类页面组件通过searchQuery状态变量管理搜索输入,实现了分类的实时过滤功能
javascript·react native·react.js·ecmascript·harmonyos
qq_177767379 小时前
React Native鸿蒙跨平台实现应用介绍页,实现了应用信息卡片展示、特色功能网格布局、权限/联系信息陈列、评分展示、模态框详情交互等通用场景
javascript·react native·react.js·ecmascript·交互·harmonyos
2603_949462109 小时前
Flutter for OpenHarmony社团管理App实战:预算管理实现
android·javascript·flutter