如何正确使用 Canvas API 下载 React 生成的 QR 码图像

11次阅读

如何正确使用 Canvas API 下载 React 生成的 QR 码图像

react-qr-code 默认渲染 SVG,不支持 toDataURL();需改用 qrcode.react 的 组件,才能调用 Canvas 原生方法实现 PNG 下载。

`react-qr-code` 默认渲染 svg,不支持 `todataurl()`;需改用 `qrcode.react` 的 `canvas>` 组件,才能调用 canvas 原生方法实现 png 下载。

在 React 应用中生成并下载 QR 码时,一个常见误区是误将 SVG 元素当作 Canvas 元素操作。例如,使用 react-qr-code 库时,其默认导出的 组件实际渲染的是 SVG 结构 (即 ),而非 元素。因此,当你通过 document.getElementById(‘qrcode’) 获取该节点并尝试调用 .toDataURL() 方法时,浏览器会抛出 TypeError: canvas.toDataURL is not a function —— 因为 SVG 元素没有该方法,只有原生 元素才具备。

✅ 正确解法是切换至支持双渲染模式的库:qrcode.react(注意包名不同,非 react-qr-code)。它提供两个专用组件:

  • :输出可缩放矢量图(适合展示,不支持 toDataURL)
  • :输出 元素(支持 toDataURL()、toBlob() 等 Canvas API)

✅ 步骤一:安装并导入正确组件

npm install qrcode.react # 或 yarn add qrcode.react
import {QRCodeCanvas} from 'qrcode.react';

✅ 步骤二:使用 渲染,并确保 ID 可选中

return (<div>     <QRCodeCanvas        id="qrcode"        level="H"        value={box.id}        size={100}        bgColor="#ffffff"       fgColor="#000000"     />     <Button onClick={downloadQRCode}>Download QR</Button>   </div> );

✅ 步骤三:安全获取 canvas 并触发下载

const downloadQRCode = () => {   const canvas = document.getElementById('qrcode') as HTMLCanvasElement;   if (!canvas) {throw new Error('QR code canvas element not found. Ensure QRCodeCanvas has the correct id.');   }    // 生成 PNG Data URL(无需 replace MIME type)const pngUrl = canvas.toDataURL('image/png');    const link = document.createElement('a');   link.href = pngUrl;   link.download = `${box.id}.png`;   document.body.appendChild(link);   link.click();   document.body.removeChild(link); };

⚠️ 注意事项

  • 不要对 toDataURL() 返回的 URL 执行 .replace(“image/png”, “image/octet-stream”):现代浏览器已支持直接下载 Data URL,强行修改 MIME 可能导致兼容性问题或失效;
  • 若需更高画质,可增大 size 属性(如 size={400}),QRCodeCanvas 会自动缩放渲染;
  • SSR(服务端渲染)环境下, 可能因无 DOM 报错,建议配合 useEffect 或动态导入(dynamic(import(…), {ssr: false}));
  • 如需支持 IE11,请添加 polyfill(toDataURL 在 IE 中仅支持 image/png,且需 canvas 已绘制完成)。

? 进阶提示 :若需导出高分辨率或带 Logo 的二维码,推荐结合 html2canvas 或 canvas-toBlob(配合 FileSaver.js)实现更灵活的导出控制。

通过以上调整,即可稳定调用 Canvas API 实现一键 PNG 下载,彻底规避“toDataURL is not a function”错误。

text=ZqhQzanResources