html2canvas图片跨域问题
需求:
页面有个弹窗,弹窗内部有网站logo、表格、第三方的图片等内容,点击打印按钮,将弹窗区域内容下载至本地
安装依赖
pnpm add html2canvas
引入
import html2canvas from 'html2canvas'
使用
<template>
...
<button @click="handlePrint()">打印</button>
</template>
<script setup>
const handlePrint = ()=>{
html2canvas(dom).then(canvas => {
const link = document.createElement("a");
link.download = `screenshot.png`;
link.href = canvas.toDataURL("image/png");
link.click();
});
}
</script>
打印过程中遇到问题
问题一: logo区域为空白
查阅html2canvas配置文档后增加useCORS: true,logo可以正常打印, 代码如下:
html2canvas(dom, {
useCORS: true,
}).then(canvas => {
const link = document.createElement("a");
link.download = `${props.returnForm.aftersaleSn}.png`;
link.href = canvas.toDataURL("image/png");
link.click();
});
问题二: 第三方图片无法打印
按上述修改后,虽logo(存放阿里云)可以打印,但另一个第三方平台的仍然无法打印,控制台报跨域问题,但无论如何设置,比如:useCORS: true、给images标签增加【crossorigin="anonymous"】,都无法避免,也没有第三方的权限,无法设置 CORS,所以只能想办法如何能够跳过跨域
方案: 请求到资源后,将图片转为base64格式,代码如下:
📢 以下为Nuxt项目示例,如果不是Nuxt项目,应该可以借助node或者让后端协助出个接口,总之就是想办法加个中转, 可以看下这篇文章https://juejin.cn/post/7402845471646285864
新建 server/routes/proxy.ts 文件
import { defineEventHandler, getQuery } from "h3";
export default defineEventHandler(async event => {
const { url } = getQuery(event);
if (!url) {
return { error: "URL is required" };
}
try {
const response = await fetch(url as string)
const buffer = await response.arrayBuffer();
const contentType = response.headers.get("content-type");
return {
data: Buffer.from(buffer).toString("base64"),
contentType
};
} catch (error: any) {
return { error: "Error loading image: " + error.message };
}
});
封装转base64方法
export const useLoadImageAsBase64 = async (url: string) => {
const { data } = await useFetch(`/proxy?url=${encodeURIComponent(url)}`);
return `data:${data.value.contentType};base64,${data.value.data}`;
};
文件中使用
const base64Img = await useLoadImageAsBase64(ite);
以上就是我在使用html2canvas过程中遇到并解决问题的过程了,希望对大家有帮助,也欢迎大家提出过程中的一些问题,如果有更好的办法可以一起讨论~