canvas.todataurl() 返回空、黑图或"data:,"的主因是图片未加载完成、canvas被跨域污染或参数错误;需在img.onload中绘图导出,设置img.crossorigin="anonymous"并确保服务端cors响应头正确,注意格式参数规范,大画布优先用toblob避免性能问题。

直接调用 canvas.toDataURL() 就能拿到 Base64 字符串,但结果为空、黑图或 "data:,",基本是因为绘制没完成、Canvas 被跨域污染,或者参数写错了。
必须等图片加载完再导出
Canvas 不会等图片自己加载好。如果 img.src = url 后立刻 drawImage 再 toDataURL,大概率导出的是空画布。
- 把绘图和导出逻辑全部放进
img.onload回调里 - 如果用
fetch + createImageBitmap或URL.createObjectURL,也要等解析完成再drawImage - 别靠
setTimeout或“感觉加载完了”这种猜测
跨域图片要加 CORS 支持
从 CDN 或其他域名加载的图片,若服务端没返回 Access-Control-Allow-Origin 响应头,Canvas 就会被污染,toDataURL() 会失败或静默返回空字符串。
用户要生成可打印的中文字帖/练习纸、导出多页 A4 PDF 报告,或把 SVG 设计稿零误差还原到 Canvas 时使用。本技能是「Canvas 内容工厂闭环」的总控,编排:网格渲染引擎(13 种教育网格+拼音标注) → 多页 PDF 导出(A4 合成) → SVG 精准复刻(坐标误差<0.001px)。触发词:生成字帖、练习纸、导出 PDF、SVG 转 Canvas、印刷级还原、A4 报告、米字格田字格。
- 前端必须显式设置
img.crossOrigin = "anonymous"(只写 HTML 的crossorigin属性不够) - 服务端响应头需包含
Access-Control-Allow-Origin: *或具体域名 - 本地开发别用
file://协议,改用http://localhost等 HTTP 服务
格式和参数要写对
toDataURL() 默认输出 PNG,但支持 JPEG、WebP 等格式,参数错一个就会退化或被忽略。
- PNG:
canvas.toDataURL("image/png")—— 第二个参数无效 - JPEG:
canvas.toDataURL("image/jpeg", 0.92)—— 质量必须是0.0–1.0的小数,传92、"0.92"或1.2都不行 - WebP:
canvas.toDataURL("image/webp", 0.7)—— Safari 16.4+ 才支持,旧版自动 fallback 到 PNG - 导出 JPEG 时若有透明区域,背景会变黑:提前用
ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, canvas.width, canvas.height)填白底
大画布建议换 toBlob 方案
超过约 1000×1000 像素(或总像素超 1000 万),toDataURL() 容易卡顿、内存爆满,iOS 还可能因 URL 长度超限导致下载失败。
- 优先用
canvas.toBlob(callback, "image/jpeg", 0.9) - 在回调里调用
URL.createObjectURL(blob)生成临时链接 - 创建
<a></a>标签,设href和download,再click()触发下载 - 下载完记得
URL.revokeObjectURL(url)释放内存
不复杂但容易忽略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










