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

React本地开发环境中Base64图片作为img src无法渲染问题排查

问题

我正在开发一个网站,从PostgreSQL数据库的bytea类型字段中获取图片。根据资料说明,图片正确编码为Base64格式并设置为img标签的src属性后应正常加载。

我已确认图片变量imgTest为字符串类型,格式为"data:image/jpeg;base64,aVZCT1J3MEtHZ29BQUFBTlN.....",但数据加载后仍只显示替代文本“test image”而非图片。以下是完整的React组件代码:

import { useState, useEffect } from 'react'
import axios from 'axios'

function Projects() {
    const [data, setData] = useState([]);
    const [offset, setOffset] = useState(0);
    const [loading, setLoading] = useState(false);
    const [initialLoad, setInitialLoad] = useState(true);
    const [projectData, setProjectData] = useState([]);

    const [imgTest, setImgTest] = useState('')

    useEffect(() => {
        loadData(0, 10);
    }, []);

    const loadData = async(offset, limit) => {
        setLoading(true);
        try {
            const response = await axios.get('http://localhost:3000/api/projects', { params: { offset, limit } });
            const newData = Array.isArray(response.data) ? response.data.rows : [response.data.rows];
            // Convert byte arrays to Base64 strings
            const processedData = newData.map(item => {
                const updatedItem = { ...item };
          
                if (item.mainphoto && item.mainphoto.data) {
                  const base64Flag = 'data:image/jpeg;base64,';
                  const mainPhotoStr = arrayBufferToBase64(item.mainphoto.data);
                  updatedItem.mainphoto = base64Flag + mainPhotoStr;
                }
          
                if (item.auxphoto1 && item.auxphoto1.data) {
                  const base64Flag = 'data:image/jpeg;base64,';
                  const auxPhotoStr = arrayBufferToBase64(item.auxphoto1.data);
                  updatedItem.auxphoto1 = base64Flag + auxPhotoStr;
                }
          
                return updatedItem;
              });
            setData((prevData) => [...prevData, ...newData]);
            setOffset(offset + limit);
        } catch (error) {
            console.log('Error fetching data:', error);
        }
        setLoading(false);
    };

    const arrayBufferToBase64 = (buffer) => {
        let binary = '';
        const bytes = new Uint8Array(buffer);
        const len = bytes.byteLength;
        for (let i = 0; i < len; i++) {
          binary += String.fromCharCode(bytes[i]);
        }
        return window.btoa(binary);
      };

    useEffect(() => {
        if (data.length > 0 && data[0]) {
            ////////////////////
            const base64Flag = 'data:image/jpeg;base64,';
            const imageString = base64Flag + arrayBufferToBase64(data[0][0].auxphoto1['data']);
            // console.log('image String',imageString);
            setImgTest(imageString);
            // console.log('image test',imgTest);
            /////////////////////

            const projectData = data.map((item, index) => (
                <div className='project' key={index} >
                    {item[0].clientname}
                    {item[0].clienttag1}
                    {item[0].clienttag2}
                    {item[0].clienttag3}
                    {/* {item[0].mainphoto && <img src={item[0].mainphoto} alt="Project Main" />} */}

                </div>
            ));
            setProjectData(projectData);
        }
      }, [data]);

      useEffect(() => {
        console.log('imgTest', imgTest);
      }, [imgTest]);

    const handleScroll = () => {
        if (window.innerHeight + document.documentElement.scrollTop === document.documentElement.offsetHeight) {
            loadData(offset, initialLoad ? 10 : 50);
            setInitialLoad(false);
        }
    };

    useEffect(() => {
        window.addEventListener('scroll', handleScroll);
        return () => window.removeEventListener('scroll', handleScroll);
    }, [offset]);

    return (
        <>
            <div className="projects">

                {/* Image below will not load. Only shows alt text */}
                {data.length > 0 ?  <img src={imgTest} alt="test image" /> : 'Not Yet'}

            </div>
        </>
    );
}

export default Projects;
排查与解决思路
  • 验证Base64编码有效性:把imgTest的完整字符串复制到浏览器地址栏直接访问,能显示图片说明编码没问题,不能显示则说明编码过程出错。
  • 检查数据结构层级:在useEffect里打印data[0],确认auxphoto1的嵌套位置和data字段类型是否为ArrayBuffer/Uint8Array,避免因层级错误拿到无效数据。
  • 匹配图片实际MIME类型:如果数据库里的图片不是JPEG格式(比如PNG),data:image/jpeg;base64,会导致加载失败,可尝试改为对应格式的MIME类型,或让后端返回图片实际类型。
  • 排查编码函数问题:测试arrayBufferToBase64是否正确处理所有字节,对比已知图片二进制数据的编码结果。注意window.btoa无法处理Unicode字符,若二进制数据含超出ASCII范围的字符,可改用Buffer.from(buffer).toString('base64')(Node.js环境)或兼容编码方式。
  • 修正状态更新逻辑:loadData中处理了processedData但未使用,反而把原始newData存入data状态,导致后续处理的是未编码数据。需将setData((prevData) => [...prevData, ...newData])改为setData((prevData) => [...prevData, ...processedData])。
  • 查看浏览器控制台错误:打开开发者工具Console面板,查看图片加载相关错误提示(如“Invalid image data”),直接定位问题根源。

内容的提问来源于stack exchange,提问作者Richard Strott

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:59:53