如何用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
相关产品推荐
相关产品推荐

