You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在浏览器中展示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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 03:47:55