Express+Mongoose开发个人资料更新页触发hasOwnProperty类型错误
问题描述
接入Mongoose的Express应用开发个人资料更新页面时,接口触发报错:TypeError: Cannot read properties of undefined (reading 'hasOwnProperty'),原接口实现代码如下:
exports.editProfilePost = async (req, res, next) => { try { const username = req.user.username; const user = await User.findOneAndUpdate({ username: username }, req.body, { new: true, }); res.redirect('/profile'); } catch (error) { next(error); } };
故障原因
这个报错是Mongoose内部执行更新逻辑时,对传入的更新参数调用hasOwnProperty方法,但拿到的参数是undefined导致的,常见诱因有两个:
- 未在Express应用中注册请求体解析中间件,表单/JSON提交的参数不会被解析,
req.body默认值为undefined - 直接将整个
req.body作为更新参数传入,没有做字段筛选和兜底校验,参数异常时就会触发报错,同时还存在越权修改敏感字段的安全风险
修复步骤
- 首先确认在路由定义前注册了Express自带的请求体解析中间件,适配表单和JSON提交场景:
// 解析form-urlencoded格式表单数据 app.use(express.urlencoded({ extended: true })); // 解析JSON格式请求数据 app.use(express.json());
- 改造更新接口逻辑,通过白名单机制筛选允许用户修改的字段,增加参数兜底校验,同时开启更新时的Schema规则校验:
exports.editProfilePost = async (req, res, next) => { try { const username = req.user.username; // 按业务需求仅保留允许用户自主修改的字段,禁止直接透传整个req.body const updateData = { nickname: req.body.nickname, bio: req.body.bio, avatar: req.body.avatar // 其他允许修改的字段可自行在此处添加 }; // 空参数兜底 if (Object.keys(updateData).length === 0) { return res.redirect('/edit-profile?error=提交内容不能为空'); } const user = await User.findOneAndUpdate( { username: username }, updateData, { new: true, // 返回更新后的文档 runValidators: true // 更新时自动执行Schema定义的字段校验 } ); res.redirect('/profile'); } catch (error) { next(error); } };
注意:
findOneAndUpdate默认不会触发Mongoose Schema校验,必须显式配置runValidators: true,才能在更新操作时生效字段格式、长度等规则,避免脏数据入库。
内容的提问来源于stack exchange,提问作者ShedeurCoder
相关产品推荐
相关产品推荐

