如何在浏览器中展示PNG图片的二进制数据?
解决Next.js中无法展示API返回的PNG二进制图片问题
问题核心在于axios默认会将响应数据解析为字符串,破坏了原始二进制字节结构,导致后续转Base64后无法生成有效的图片数据。下面是两种可行的解决方法:
方法1:指定响应类型为arraybuffer,转Base64展示
通过设置axios的responseType为arraybuffer,确保获取到原始二进制数据,再转换为Base64格式:
import { useState, useEffect } from 'react'; import axios from 'axios'; const EsimQrCode = () => { const [esimQrCode, setEsimQrCode] = useState<ArrayBuffer | null>(null); useEffect(() => { loadQrCode(); }, []); const loadQrCode = async () => { try { const res = await axios.get(API_GET_QRCODE(), { responseType: 'arraybuffer', // 关键:获取原始二进制数组 }); setEsimQrCode(res.data); } catch (err) { console.error('加载二维码失败:', err); } }; if (!esimQrCode) { return <div>加载中...</div>; } const base64Data = Buffer.from(esimQrCode).toString('base64'); return <img src={`data:image/png;base64,${base64Data}`} alt="eSIM二维码" />; }; export default EsimQrCode;
方法2:使用Blob URL展示(更适合大图片)
直接获取Blob类型数据,通过浏览器的URL.createObjectURL生成临时链接,这种方式更节省内存,且无需Base64转换:
import { useState, useEffect, useRef } from 'react'; import axios from 'axios'; const EsimQrCode = () => { const [imgUrl, setImgUrl] = useState<string | null>(null); const blobUrlRef = useRef<string | null>(null); useEffect(() => { loadQrCode(); // 组件卸载时释放Blob URL,避免内存泄漏 return () => { if (blobUrlRef.current) { URL.revokeObjectURL(blobUrlRef.current); } }; }, []); const loadQrCode = async () => { try { const res = await axios.get(API_GET_QRCODE(), { responseType: 'blob', // 直接获取Blob对象 }); const url = URL.createObjectURL(res.data); blobUrlRef.current = url; setImgUrl(url); } catch (err) { console.error('加载二维码失败:', err); } }; if (!imgUrl) { return <div>加载中...</div>; } return <img src={imgUrl} alt="eSIM二维码" />; }; export default EsimQrCode;
关键注意事项
- 必须设置
responseType为arraybuffer或blob,否则axios会自动将二进制数据转成UTF-8字符串,导致字节损坏 - Next.js中,
URL.createObjectURL属于浏览器专属API,上述代码通过useEffect确保仅在客户端执行 - 使用Blob URL时,务必在组件卸载时调用
URL.revokeObjectURL释放资源,防止内存泄漏
内容的提问来源于stack exchange,提问作者Trung Do Xuan
相关产品推荐
相关产品推荐

