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

React上传Base64图片至MongoDB时偶现photo字段为false

React转Base64图片上传MongoDB偶现photo字段为"false"的问题

开发网站时,通过React将图片转换为Base64格式后上传至后端并存入MongoDB数据库,偶发异常:从数据库取回图片数据时,部分记录的photo字段值为"false",无法正常显示,其他记录的Base64图片数据正常,重新上传该图片有时可恢复正常。

问题示例数据

(3) [{…}, {…}, {…}]
0: 
  photo: "false"
  __v: 0
  _id: "650ce3fb077e8bd7795561e0"
  [[Prototype]]: Object
1: 
  photo: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAA..."
  __v: 0
  _id: "650ce411077e8bd7795561e4"
  [[Prototype]]: Object
2: 
  photo: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAA..."
  __v: 0
  _id: "650ce413077e8bd7795561e6"
  [[Prototype]]: Object
length: 3

后端uploadImage路由代码

import express from 'express';
import * as dotenv from 'dotenv';
import Image from '../mongodb/models/image.js';
dotenv.config();

const router = express.Router();

router.route('/').get(async (req, res) => {
  try {
    await Image.find({}).then(data => {
      res.status(200).json({ success: true, data: data });
    });
  } catch (err) {
    console.log(err)
    res.status(500).json({ success: false, message: 'Fetching posts failed, please try again' });
  }
});

router.route('/').post(async (req, res) => {
  try {
    const { base64 } = req.body;
    await Image.create({
      photo: base64,
    });
    res.status(200).json({ success: true});
  } catch (err) {
    console.log(err)
    res.status(500).json({ success: false, message: 'Unable to upload the image, please try again' });
  }
});

export default router;

React端上传图片代码

const handleImageUpload = async (e) => {
  const file = e.target.files[0];
  var reader = new FileReader();
  reader.readAsDataURL(file)
  reader.onload = () => {
    // base 64
    // console.log(reader.result)
    SetImage(reader.result)
  }
  reader.onerror = e  => {
    console.log("Reader Error " , e)
  }
 
  if (file) {
    const imageUrl = URL.createObjectURL(file);
    setForm({ ...form, file, photo: imageUrl });
    try {
      const response = await fetch('http://localhost:8080/api/v1/uploadImage', {
        method: 'POST',
        headers: {
          "Content-Type": "application/json",
          Accept : "application/json",
          "Access-Control-Allow-Origin": "*",
        },
        body: JSON.stringify({
          base64 : image
        }),
      });
      console.log(response);
      if (response.ok) {
        console.log('Image uploaded and saved successfully!');
      } else {
        console.error('Failed to upload image');
      }
    } catch (error) {
      console.error('Error uploading image:', error);
    }
  };
}

问题原因

FileReader.readAsDataURL是异步操作,你在调用fetch上传时,image状态可能还未完成更新(SetImage也是异步的),此时上传的base64参数可能是初始值(比如初始为false),导致后端存入数据库的photo字段为字符串"false"。

解决方法

将上传逻辑移至reader.onload回调内,确保拿到正确的Base64数据后再发起请求:

const handleImageUpload = async (e) => {
  const file = e.target.files[0];
  if (!file) return;

  const reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onload = async () => {
    const base64Data = reader.result;
    SetImage(base64Data);

    const imageUrl = URL.createObjectURL(file);
    setForm({ ...form, file, photo: imageUrl });

    try {
      const response = await fetch('http://localhost:8080/api/v1/uploadImage', {
        method: 'POST',
        headers: {
          "Content-Type": "application/json",
          Accept: "application/json",
        },
        body: JSON.stringify({
          base64: base64Data // 直接使用reader.result,不依赖状态更新
        }),
      });
      console.log(response);
      if (response.ok) {
        console.log('Image uploaded and saved successfully!');
      } else {
        console.error('Failed to upload image');
      }
    } catch (error) {
      console.error('Error uploading image:', error);
    }
  };
  reader.onerror = (err) => {
    console.log("Reader Error ", err);
  };
};

额外优化建议

  • 后端增加参数校验:判断base64是否以data:image/开头,不符合则返回错误,避免存入无效数据。
  • 移除请求头中的"Access-Control-Allow-Origin": "*",该字段是后端设置的响应头,前端请求添加无意义。

内容的提问来源于stack exchange,提问作者Nutrino DAYA

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 08:18:26