Mongoose上传图片更新用户信息返回空对象问题求助
核心错误点
upload.single("productImage")是multer返回的中间件函数,你只在路由处理函数里写了调用语句但没有挂载执行,根本不会处理上传的文件;且单文件上传场景下,文件数据存在req.file字段,不是多文件场景才会生成的req.files。findByIdAndUpdate是异步方法,你没有加await等待执行完成,拿到的只是pending状态的Promise对象,不是实际的数据库文档;且方法默认返回更新前的旧数据,不传{new: true}配置拿不到更新后的结果。- 图片数据字段定义为Buffer类型,你传入的
fs.createReadStream是文件流对象,类型不匹配无法存入数据库;且你拼接的路径是文件夹路径,没有指向具体上传的文件,根本读不到正确的文件内容。 - Schema配置项拼写错误:
timeStamps正确写法是timestamps,否则自动生成创建、更新时间的功能不会生效;贴出的模型代码最后导出语句截断,需要补全为export default User。 - 响应逻辑顺序错误:数据库更新、文件处理都没执行完就直接返回
res.send("ok"),既没有等待异步操作完成,也没有把携带图片信息的更新后用户数据返回给前端,前端自然拿不到渲染数据。 - Schema中image字段的定义多余嵌套了
type字段,会被Mongoose识别为类型声明,导致字段结构校验异常。
修正代码
1. 修复User模型定义
import mongoose from "mongoose"; const userSchema = new mongoose.Schema({ name: {type: String, required: true}, fname: {type: String, required: true}, phone: {type: String, required: true}, email: {type: String, required: true, unique: true}, password: {type: String, required: false}, // 移除多余的type嵌套,正确定义嵌套文档结构 image: { name: String, img: { contentType: String, data: Buffer }, required: false }, isAdmin: {type: Boolean, default: false, required: true}, }, { timestamps: true // 修正配置项拼写 }); const User = mongoose.model("User", userSchema); export default User; // 补全导出语句
2. 修复上传接口逻辑
提前配置好multer实例,指定文件临时存储目录后,按如下逻辑写接口:
import fs from "fs/promises"; import path from "path"; // 提前引入你初始化好的multer upload实例、User模型 // 把upload.single中间件直接挂载到路由上,才会执行文件解析 userRouter.post("/upload/:id", upload.single("productImage"), async(req, res)=> { try { if (!req.file) { return res.status(400).send({error: "未接收到上传图片"}); } // 读取上传文件的二进制Buffer,匹配Schema定义的Buffer类型 const fileBuffer = await fs.readFile(req.file.path); // 等待数据库更新完成,传入new:true返回更新后的文档 const updatedUser = await User.findByIdAndUpdate( req.params.id, { $set: { image: { name: req.file.originalname, img: { contentType: req.file.mimetype, data: fileBuffer } } } }, {new: true} ); // 所有逻辑执行完成后,把更新后的用户数据返回给前端 res.send(updatedUser); console.log(updatedUser); // 可选:读取完文件后删除临时目录下的上传文件,避免占磁盘空间 await fs.unlink(req.file.path); } catch (err) { console.error(err); res.status(500).send({error: "图片上传更新失败"}); } })
前端渲染适配
接口返回的图片数据是Buffer格式,不能直接赋值给img标签的src,需要转成base64格式的DataURL再使用:
// 前端拿到接口返回的updatedUser后处理图片地址 const renderImgSrc = `data:${updatedUser.image.img.contentType};base64,${updatedUser.image.img.data.toString('base64')}` // 将renderImgSrc绑定到<img>标签的src属性即可正常渲染图片
内容的提问来源于stack exchange,提问作者Borhen Kalboussi
相关产品推荐
相关产品推荐

