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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 00:15:45