Node.js+Express+Mongoose新增Product提示userId必填报错
问题根因
报错是两个代码逻辑错误导致的:
- 全局用户挂载中间件的异步逻辑处理错误:
User.findById是异步数据库操作,你把next()写在了异步操作外部,还注释掉了then回调里的next(),请求会在数据库查询完成、req.user被赋值前就进入后续路由处理流程,最终控制器拿到的req.user是undefined,触发userId required校验错误。 userId字段赋值不规范:req.user是完整的Mongoose文档对象,而你的Product模型中userId定义为ObjectId类型,直接传入整个文档可能存在隐式转换风险。
修复步骤
- 修正
app.js中的用户挂载中间件,将请求放行逻辑放到异步查询完成的回调内:
app.use((req, res, next) => { User.findById("62c71d0ab0312958a8082d6f") .then((user) => { req.user = user; next(); // 拿到用户数据后再放行请求 }) .catch((err) => console.log(err)); // 删除此处原本放在异步操作外的next()调用 });
- 修正新增商品控制器中的
userId赋值,直接传入用户的_id字段:
exports.postAddProduct = (req, res, next) => { const product = new Product({ title: req.body.title, price: req.body.price, description: req.body.description, imageUrl: req.body.imageUrl, userId: req.user._id // 直接取用户ID值,匹配Schema定义的ObjectId类型 }); product .save() .then((result) => { console.log("Product created!"); res.redirect("/admin/products"); }) .catch((err) => { console.log(err); }); };
可选优化
你当前数据库连接后的初始化用户逻辑没有等待用户写入完成就启动服务,极端场景下会出现查询不到初始用户的问题,可以调整为等待初始化完成再启动服务:
mongoose .connect("你的MongoDB连接地址") .then(async (result) => { const existingUser = await User.findOne(); if (!existingUser) { const newUser = new User({ name: 'Aimen', email: 'Aimen@', cart: { items: [] } }); await newUser.save(); } console.log("Connected to MongoDB"); app.listen(3000); }) .catch((err) => console.log(err));
修改完成后重启服务即可正常提交商品数据。
内容的提问来源于stack exchange,提问作者Aimen SAYOUD
相关产品推荐
相关产品推荐

