调用 canvas.toDataURL() 前须确保图像加载完成、Canvas 未跨域污染、参数正确:图片需在 onload 中绘制导出;跨域图需服务端支持 CORS 且 img.crossOrigin = "anonymous";格式参数须规范(如 JPEG 质量传 0.92);大图建议用 toBlob + createObjectURL 下载。

直接调用 canvas.toDataURL() 即可,但必须确保图像已完整绘制、Canvas 未被跨域污染,且参数传得正确。
必须等图片加载完成再导出
Canvas 不会自动等待图片加载。如果在 img.src = url 后立刻调用 toDataURL(),得到的往往是空白或黑图。
- 把绘图和导出逻辑全部放进
img.onload回调里 - 不要依赖
setTimeout或“看起来加载完了”这种猜测 - 若用
fetch + createObjectURL或createImageBitmap,也要等解析完成再绘制
跨域图片要加 CORS 支持
从其他域名加载图片(比如 CDN)时,Canvas 会被“污染”,toDataURL() 就会失败或返回空字符串 "data:,"。
- 服务端需返回
Access-Control-Allow-Origin: *(或具体域名) - 前端设置
img.crossOrigin = "anonymous"(仅写 HTML 的crossorigin属性不够) - 本地开发避免用
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"都不行 - WebP:
canvas.toDataURL("image/webp", 0.7)—— Safari 16.4+ 才支持,旧版自动 fallback 到 PNG - 透明区域导出 JPEG 会变黑:提前用
ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, w, h)填白底
大画布或下载场景建议换方案
超过约 1000×1000 像素的 Canvas,toDataURL() 容易卡顿、内存爆满,或生成超长 URL 导致 iOS 下载失败。
- 导出大图优先用
canvas.toBlob()+URL.createObjectURL() - 触发下载别直接赋值给
window.location.href,应创建<a>标签,设href和download,再click()并及时移除 - 需要处理整个网页截图?用
html2canvas渲染 DOM 到 Canvas,再调用toDataURL()



















