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

如何用NodeJS和MongoDB实现用户关联图片的存储与读取?

问题描述

刚接触NodeJS和MongoDB,希望实现数据库中与用户关联的图片添加和读取功能。已创建Mongoose Schema并尝试用GridFS和Multer实现,但图片存储后前端React无法正确渲染。

User模型

const mongoose = require("mongoose");
const uniqueValidator = require("mongoose-unique-validator");

const userSchema = mongoose.Schema(
  {
    first: { type: String, required: true },
    last: { type: String, required: true },
    username: { type: String, required: true, unique: true },
    password: { type: String, required: true },
    img: {data: Buffer, type: String },
  },
  { timestamps: true }
);
userSchema.plugin(uniqueValidator);
module.exports = mongoose.model("User", userSchema);

User控制器

const user = require('../models/user');
var User = require('../models/user');


exports.get_user = async (req, res, next) => {
    const { username, password } = req.body;
    let user_obj = await User.findOne({ username: username, password: password })
    res.status(200).json(user_obj);
}

exports.create_user = async (req, res, next) => {
    const { first, last, username, password,img} = req.body;
    const user_obj = new User({ first: first, last: last, username, password,img: req.file.filename});
     
     
    await user_obj.save();
    res.status(200).json('user creation succeded');
}

User路由

const express = require("express");
const router = express.Router();
const userController = require('../controllers/userController');
const upload = require('../middleware/upload');

router.post("/create_user", upload.single('img'), userController.create_user);
//router.post("/create_user", userController.create_user);
router.post("/update_user", userController.update_user);
router.post("/get_user", userController.get_user);
router.get("/delete_user/:username", userController.delete_user);


module.exports = router;

解决方案

你的代码目前仅将图片文件名存入User文档,但前端无法直接通过文件名渲染图片,需做以下调整:

1. 修正User Schema的img字段

当前img字段定义存在矛盾(同时声明data: Buffer和type: String),若用Multer将图片存储到本地服务器,只需保留文件名字段:

img: { type: String }

2. 配置Express静态文件服务

在项目主入口文件(如app.js)中添加静态文件托管,让前端可以访问上传的图片:

const express = require('express');
const app = express();
// 假设Multer将图片存入项目根目录的uploads文件夹
app.use('/uploads', express.static('uploads'));

3. 前端React正确渲染图片

从后端获取用户数据后,将文件名拼接成完整的访问URL:

// React组件示例
function UserProfile({ user }) {
  return (
    <div>
      <h2>{user.first} {user.last}</h2>
      {/* 拼接静态文件服务路径与文件名 */}
      <img src={`/uploads/${user.img}`} alt="用户头像" />
    </div>
  );
}

4. 若使用GridFS存储图片到MongoDB的调整方案

如果选择用GridFS将图片直接存在MongoDB中,需修改存储逻辑:

  • 存储时将GridFS生成的文件ID存入User的img字段
  • 新增一个接口根据文件ID读取图片并返回给前端

新增获取图片的路由与控制器

// 路由文件中新增
router.get('/user-avatar/:fileId', async (req, res) => {
  const bucket = new mongoose.mongo.GridFSBucket(mongoose.connection.db);
  const downloadStream = bucket.openDownloadStream(req.params.fileId);
  downloadStream.pipe(res);
});

前端渲染方式

<img src={`/api/user-avatar/${user.img}`} alt="用户头像" />

内容的提问来源于stack exchange,提问作者Dah Sidi Abdallah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:25:18