vue3 html2canvas 网络图片 空白 及使用

本文介绍了如何使用html2canvas库在JavaScript中获取指定div的内容并转换为base64格式图片,支持跨域和不同浏览器的兼容性处理,包括PDF下载和直接下载功能。
/* <div id="capture" ref="divDom">
      <img :src="img">
    </div> */
import html2canvas from 'html2canvas'
const img = ref("https://tse1-mm.cn.bing.net/th/id/OIP-C.cykW2JFIAZEv6vWFflfjygHaEZ?pid=ImgDet&rs=1")
const base64img = ref()
const weeklyReport = () => {
  console.log('生成周报')
  html2canvas(document.querySelector('#capture'), {
    backgroundColor: "#ffffff",
    allowTaint: true,  //开启跨域
    useCORS: true,
    scrollY: 0,
    scrollX: 0,
  }).then((canvas) => {
    // 转换成base64格式,这个格式可以挂载到img里,也可以下载下来,也可以打压缩包下载下来
    const base64 = canvas
      .toDataURL()
      .replace(/^data:image\/(png|jpg);base64,/, '')
    base64img.value = `data:image/png;base64,${base64}`
    console.log(base64img.value)

    // if (window.navigator.msSaveOrOpenBlob) {

    //   let bstr = atob(base64img.value.split(",")[1]);
    //   let n = bstr.length;
    //   let u8arr = new Uint8Array(n);
    //   while (n--) {
    //     u8arr[n] = bstr.charCodeAt(n);
    //   }
    //   let blob = new Blob([u8arr]);
    //   window.navigator.msSaveOrOpenBlob(blob, "周报" + "." + "pdf");
    // } else {
    //   // 这里就按照chrome等新版浏览器来处理
    //   let a = document.createElement("a");
    //   a.href = base64img.value;
    //   a.setAttribute("download", "周报");
    //   a.click();
    // }
  });
}

### 解决 Vue3Html2canvas 无法生成 Base64 图片的问题 在 Vue3 项目中使用 Html2canvas 时,可能会遇到无法生成 Base64 图片的问题。以下是一些可能的原因及解决方案。 #### 原因分析 1. **跨域问题**:如果页面中的图片资源来自其他域名,并且未正确设置跨域属性,Html2canvas 将无法加载这些图片,导致生成的截图不完整或为空白。 2. **CORS 配置缺失**:即使设置了 `useCORS: true`,但如果服务器未配置 CORS,则图片仍然无法正常加载[^1]。 3. **图片加载未完成**:如果在图片尚未完全加载的情况下调用 Html2canvas,可能会导致生成的截图缺少部分图片内容。 4. **Html2canvas 版本问题**:不同版本的 Html2canvas 对某些功能的支持可能存在差异,确保使用的是最新稳定版本。 #### 解决方案 ##### 方法一:确保跨域图片正确加载 通过设置图片的 `crossOrigin` 属性为 `anonymous`,可以解决跨域问题。以下是示例代码: ```javascript async htmlToImage() { const element = this.$refs.canvas; const images = element.querySelectorAll(&#39;img&#39;); await Promise.all( Array.from(images).map((img) => { return new Promise((resolve, reject) => { img.setAttribute(&#39;crossOrigin&#39;, &#39;anonymous&#39;); if (img.complete && img.naturalHeight !== 0) { resolve(); } else { img.onload = resolve; img.onerror = reject; } }); }) ); const _html2canvas = await html2canvas(element, { useCORS: true }); this.formData.base64 = _html2canvas.toDataURL(&#39;image/png&#39;); console.log(this.formData.base64); } ``` 此代码确保所有图片都已加载完成,并且设置了正确的跨域属性。 ##### 方法二:检查服务端 CORS 配置 如果图片资源托管在第三方服务器上,需要确保服务器支持 CORS 请求。例如,在 Nginx 中可以通过以下配置实现: ```nginx location /images/ { add_header Access-Control-Allow-Origin *; } ``` 此配置允许所有来源访问 `/images/` 目录下的资源[^3]。 ##### 方法三:更新 Html2canvas 版本 确保使用的是最新版本的 Html2canvas,因为旧版本可能存在兼容性问题。可以通过以下命令安装最新版本: ```bash npm install --save html2canvas ``` 然后在项目中引入并使用: ```javascript import html2canvas from "html2canvas"; ``` ##### 方法四:等待图片加载完成 在调用 Html2canvas 之前,确保所有图片均已加载完成。可以通过监听图片的 `load` 事件来实现: ```javascript async waitForImages(element) { const images = element.querySelectorAll(&#39;img&#39;); await Promise.all( Array.from(images).map((img) => { return new Promise((resolve, reject) => { if (img.complete && img.naturalHeight !== 0) { resolve(); } else { img.onload = resolve; img.onerror = reject; } }); }) ); } ``` 将上述方法与 Html2canvas 结合使用,可以确保生成的截图包含所有图片内容。 --- ### 示例代码:完整解决方案 以下是一个完整的示例代码,展示了如何在 Vue3使用 Html2canvas 生成 Base64 图片: ```javascript <template> <div> <div ref="canvas" id="record"> <img src="https://example.com/image.jpg" alt="Example Image" /> </div> <button @click="htmlToImage">Generate Image</button> </div> </template> <script> import html2canvas from "html2canvas"; export default { methods: { async htmlToImage() { const element = this.$refs.canvas; // 确保所有图片已加载完成 await this.waitForImages(element); // 调用 Html2canvas const _html2canvas = await html2canvas(element, { useCORS: true }); // 生成 Base64 图片 this.formData.base64 = _html2canvas.toDataURL(&#39;image/png&#39;); console.log(this.formData.base64); }, async waitForImages(element) { const images = element.querySelectorAll(&#39;img&#39;); await Promise.all( Array.from(images).map((img) => { return new Promise((resolve, reject) => { img.setAttribute(&#39;crossOrigin&#39;, &#39;anonymous&#39;); if (img.complete && img.naturalHeight !== 0) { resolve(); } else { img.onload = resolve; img.onerror = reject; } }); }) ); }, }, data() { return { formData: { base64: &#39;&#39;, }, }; }, }; </script> ``` --- ### 注意事项 - 如果图片资源托管在第三方平台且不支持 CORS,则只能通过 Base64 转换解决。 - 在生产环境中,建议限制 CORS 的允许来源,以提高安全性。 - 使用 `useCORS: true` 参数时,确保服务端支持跨域请求。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呱嗨喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值