不容错过的前端快照功能(html2canvas)
背景结合后端数据生成运营推广页面,用户通过保存操作将推广页面保存为图片进行分享和传播。其中涉及到的前端主要技术点:dom转图片保存图片到本地了解 CORSCORS(Cross-Origin Resource Sharing,跨域资源共享),同源安全策略默认阻止跨域获取资源,通过CORS给了Web服务器这样的权限,即服务器可以选择,允许跨域请求访问到它们的资源。CORS由一系列传输的HTTP头组成,
背景
结合后端数据生成运营推广页面,用户通过保存操作将推广页面保存为图片进行分享和传播。其中涉及到的前端主要技术点:
dom
转图片- 保存图片到本地
了解 CORS
CORS
(Cross-Origin Resource Sharing,跨域资源共享),同源安全策略默认阻止跨域获取资源,通过CORS
给了Web
服务器这样的权限,即服务器可以选择,允许跨域请求访问到它们的资源。CORS
由一系列传输的HTTP
头组成,这些HTTP
头决定浏览器是否阻止前端JavaScript
代码获取跨域请求的响应。
什么情况下需要CORS
:
- 由
XMLHttpRequest
或Fetch
发起的跨源HTTP
请求。 Web
字体 (CSS
中通过@font-face
使用跨源字体资源)。WebGL
贴图。- 使用
drawImage
将Images/video
画面绘制到canvas
。
技术方案
html2canvas
提供将dom
绘制到canvas
,file-saver
:提供将Blob
导出为本地文件。流程既是:dom
=> html2canvas
=> canvas
=> blob
=> file-saver
=> image
import html2canvas from 'html2canvas';
import { saveAs } from 'file-saver';
const dom = document.getElementById('html-to-canvas')
html2canvas(dom, {
useCORS: true,
})
then(canvas => {
const blob = canvas.toBlob((blod: Blob | null) => {
if (blob) {
saveAs(blob, 'html2canvas.png')
}
})
})
问题与方案
跨域
由于canvas
对于图片资源的同源限制,如果画布中包含跨域的图片资源则会污染画布,如上对于CORS
介绍中用讲到使用drawImage
将Images/video
画面绘制到canvas
需要配合CORS
使用。可以通过配置useCORS: true
,且img
标签配置crossOrigin = 'anonymous'
支持CORS
。
资源加载不全
图片资源在生成快照是还未完全加载,造成快照内容不全,通过Promise.all
保证图片资源加载完成,并开启快照生成功能。
// 加载图片
const toBlobURL = (url: string) => {
return new Promise((resolve, reject) => {
const canvasDom = window.document.createElement('canvas')
const ctx = canvasDom.getContext('2d')
const img = window.document.createElement('img')
img.crossOrigin = 'anonymous'
img.src = url
img.onload = () => {
canvasDom.width = img.width
canvasDom.height = img.height
ctx!.drawImage(img, 0, 0)
canvasDom.toBlob((blob: Blob | null) => {
if (blob) {
const blobURL = URL.createObjectURL(blob)
resolve(blobURL)
} else {
reject()
}
})
}
img.onerror = () => {
reject()
}
})
}
// 加载内容
const imgLists = imgContainerDom.querySelectorAll('img')
Promise.all(
Array.from(imgLists).map((imgDom, i) => {
return toBlobURL(imgDom.src)
}),
)
.then(res => {
for (let i = 0; i < imgLists.length; i++) {
imgLists[i].src = (res as any)[i]
}
})
.catch((e) => {
console.log('enter error handle')
console.log(e)
})
微信导出不成功
issues:https://github.com/niklasvh/html2canvas/issues/2205
建议使用"html2canvas": "1.0.0-rc.4"
更多推荐
所有评论(0)