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

MERN Stack中React前端无法显示图片问题求助

MERN栈React前端图片无法显示问题解决

问题概述

在MERN栈开发中,React前端无法渲染图片。已使用multer将图片文件名存储到MongoDB,但问题未解决,尝试过页面测试、AI工具等方法均无效。

前端代码(React)

import React, { useState, useEffect } from 'react';
import { MDBIcon } from 'mdb-react-ui-kit';
import '../card/card.css';
import Carinfo from '../comp/carinfo';
import { useNavigate } from "react-router-dom";

function Cars() {
  const [cars, setCars] = useState([]);
  const [query, setQuery] = useState("");
  const navigate = useNavigate();

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch('http://localhost:7000/images');
        const data = await response.json();
        setCars(data.files);
      } catch (error) {
        console.log(error);
      }
    }
    fetchData();
  }, []);

  return (
    <>
      <div className="search-input">
        <a href="#" target="_blank" hidden />
        <input
          type="text"
          placeholder="Search cars"
          onChange={(event) => setQuery(event.target.value)}
        />
        <div className="icon">
          <i className="fas fa-search" />
        </div>
      </div>

      <h1 id="cars-title">
        Cars <MDBIcon fas icon="car" />
      </h1>

      <div className="card-container">
        {cars &&
          cars
            .filter((car) => {
              if (query === '') {
                return car;
              } else if (car.carName.toLowerCase().includes(query.toLowerCase())) {
                return car;
              }
            })
            .map((car) => (
              <div className="img-card iCard-style1" key={car._id}>
                <div className="card-content">
                  <div className="card-image">
                    <h1 className="card-title">{car.carName}</h1>
                    <img src={car.carImg} alt="img" />
                  </div>
                  <div className="card-text">
                    <h3>{car.carType}</h3>
                    <h3 className="year">car Year: {car.carYear}</h3>
                    <h6 className="km">{car.carColor}</h6>
                    <span className="price">
                      price is: <h4>{car.carPrice}$</h4>
                    </span>
                    <h5 className="km">
                      {car.carKm} km <i className="fa-solid fa-gauge" />
                    </h5>
                    <h6 className="carD">{car.carDescription}</h6>
                  </div>
                </div>
                <div className="card-link">
                  <button
                    id="btn-card"
                    onClick={() =>
                      navigate('/Carinfo', {
                        state: {
                          carName: car.carName,
                          carYear: car.carYear,
                          carPrice: car.carPrice,
                          carKm: car.carKm,
                          carColor: car.carColor,
                          carImg: car.carImg,
                          carDescription: car.carDescription,
                          carType: car.carType,
                        },
                      })
                    }
                  >
                    <span id="read">Read Full</span>
                  </button>
                </div>
              </div>
            ))}
      </div>
    </>
  );
}

export default Cars;

后端代码(Node.js/Express)

const { MongoClient } = require('mongodb');
const url = "mongodb://127.0.0.1:27017/";
const express = require('express');
const multer = require('multer');
const dbName = "cars";
const collectionName = "car-name";
const app = express();
const local = 7000;
const bodyParser = require('body-parser');

// CORS配置
app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader(
    'Access-Control-Allow-Headers',
    'Origin, X-Requested-With, Content-Type, Accept, Authorization'
  );
  res.setHeader('Access-Control-Allow-Methods', 'PUT,GET, POST, PATCH, DELETE');
  next();
});

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));

// multer存储配置
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'C:/Users/tahaa/OneDrive/Desktop/yourcar edit/front-end/src/cars/');
  },
  filename: (req, file, cb) => {
    cb(null, file.originalname);
  }
});

const upload1 = multer({ storage: storage });

// 上传接口
app.post('/upload', upload1.single('file'), (req, res) => {
  try {
    const file = req.file;
    const { carName, carType, carYear, carColor, carDescription, carPrice, carKm } = req.body;

    MongoClient.connect(url, { useUnifiedTopology: true })
      .then((client) => {
        const db = client.db(dbName);
        const collection = db.collection(collectionName);
        const myobj = {
          carName,
          carType,
          carYear,
          carColor,
          carImg: file.filename,
          carDescription,
          carPrice,
          carKm
        };
        return collection.insertOne(myobj);
      })
      .then(() => {
        res.json({ message: 'File uploaded successfully!' });
        console.log('File uploaded successfully!');
      })
      .catch((err) => {
        console.error('Failed to save image path in MongoDB', err);
        res.status(500).json({ message: 'Failed to save image path in MongoDB' });
      });
  } catch (error) {
    console.error('Failed to upload file', error);
    res.status(500).json({ message: 'Failed to upload file' });
  }
});

// 获取车辆数据接口
app.get('/images', async (req, res) => {
  try {
    const client = await MongoClient.connect(url, { useUnifiedTopology: true });
    const database = client.db('cars');
    const inputs = database.collection('car-name');
    const count = await inputs.estimatedDocumentCount();

    if (count === 0) {
      return res.status(404).send({ message: 'Error: No cars found' });
    }

    const result = await inputs.find({}).toArray();
    console.log(result);
    res.send({ files: result });
  } catch (error) {
    console.log(error);
    res.status(500).send({ message: 'Error: Something went wrong', error });
  }
});

app.listen(local, () => console.log(`Server running on http://localhost:${local}`));

问题根源与解决方案

1. 图片存储路径错误

当前后端将图片存储在React项目的src/cars目录下,React编译后不会直接暴露src目录下的文件,导致前端无法访问。

修改方案:

  • 在后端项目根目录创建public/images文件夹(若不存在)
  • 修改multer的destination为后端的静态文件目录:
    const storage = multer.diskStorage({
      destination: (req, file, cb) => {
        cb(null, './public/images/'); // 改为后端public/images目录
      },
      filename: (req, file, cb) => {
        cb(null, file.originalname);
      }
    });
    

2. 静态文件托管配置问题

当前后端仅托管public目录,需明确托管public/images并指定访问路径:

修改方案:

// 替换原有的app.use(express.static('public'))
app.use('/images', express.static('public/images'));

3. 前端图片路径错误

前端直接使用数据库中的文件名作为src,没有指向后端的静态文件服务地址。

修改方案:
在React组件中,将img标签的src拼接为后端的完整访问URL:

<img src={`http://localhost:7000/images/${car.carImg}`} alt="car image" />

4. 冗余multer配置清理

后端中存在重复的upload = multer()和app.use(upload.array()),这会干扰文件上传逻辑,建议删除:

// 删除以下两行冗余代码
// var upload = multer();
// app.use(upload.array());

完成以上修改后,重启后端服务,重新上传图片即可在前端正常显示。

内容的提问来源于stack exchange,提问作者Taha ik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 23:56:58