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

为何func2无需设置ValidateBeforeSave:false即可运行,而func1却不行?

为何func1必须关闭保存验证,而func2不需要?

核心原因:Schema验证规则与字段存在性的差异

1. 先明确Schema的关键验证逻辑

你的用户Schema中,passwordConfirm字段包含两个强制验证:

passwordConfirm: {
  required: [true, 'password confimr must be set'],
  validate: {
    validator: function (val) {
      return val === this.password;
    },
  },
},

同时在实际用户认证场景中,通常会通过pre save钩子在首次保存用户时移除passwordConfirm(不需要将确认密码存入数据库),示例钩子代码如下:

userSchema.pre('save', function(next) {
  if (!this.isModified('password')) return next();
  // 此处一般会对password进行加密处理
  this.passwordConfirm = undefined; // 移除确认密码字段,不存入数据库
  next();
});

这意味着:从数据库查询返回的用户文档不包含passwordConfirm字段。

2. func1的执行问题

  • 通过User.findOne取出用户后,文档中没有passwordConfirm字段
  • 调用createResetToken仅修改了passwordResetToken,未设置passwordConfirm
  • 执行user.save()时,mongoose会触发所有字段的验证规则:
    • passwordConfirm的required验证直接失败(字段不存在)
    • 因此必须添加{ validateBeforeSave: false }跳过所有验证,才能成功保存

3. func2能正常运行的原因

  • 同样取出无passwordConfirm字段的用户文档
  • 手动设置了user.password和user.passwordConfirm:
    • 满足passwordConfirm的required规则(字段有值)
    • 自定义验证器通过(passwordConfirm与password值完全一致)
  • 所有验证规则都符合要求,因此无需关闭验证即可成功执行user.save()

内容的提问来源于stack exchange,提问作者Sajjad Jafari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:06:29