【问题标题】:Mongoose - validate email syntaxMongoose - 验证电子邮件语法
【发布时间】:2023-03-14 15:20:01
【问题描述】:

我有一个供用户使用的猫鼬模式 (UserSchema),我想验证电子邮件是否具有正确的语法。我目前使用的验证如下:

UserSchema.path('email').validate(function (email) {
  return email.length
}, 'The e-mail field cannot be empty.')

不过,这只检查字段是否为空,而不检查语法。

是否已经存在可以重复使用的东西,或者我必须想出自己的方法并在 validate 函数中调用它?

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    您还可以使用 ma​​tchvalidate 属性在架构中进行验证

    例子

    var validateEmail = function(email) {
        var re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
        return re.test(email)
    };
    
    var EmailSchema = new Schema({
        email: {
            type: String,
            trim: true,
            lowercase: true,
            unique: true,
            required: 'Email address is required',
            validate: [validateEmail, 'Please fill a valid email address'],
            match: [/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/, 'Please fill a valid email address']
        }
    });
    

    【讨论】:

    • 不错的解决方案。但唯一的问题是它没有通过 eslint 正则表达式规则。你能更新一下吗?
    • validatematch有什么区别?
    • @Anatoly validate 指定要调用验证的函数(不需要使用正则表达式),match 直接指定验证正则表达式。
    • 提议的正则表达式只允许 2-3 个字母的 TLD,但也有更长的 TLD en.wikipedia.org/wiki/List_of_Internet_top-level_domains,单字母 TLD 在技术上是正确的(即使目前没有这样的)所以我的建议是使用带有w+ 的正则表达式而不是w{2,3}
    • plus + 是电子邮件的有效字符,此正则表达式不允许像user+alias@gmail.com 这样的电子邮件,请考虑使用另一个正则表达式,例如/^.+@(?:[\w-]+\.)+\w+$/
    【解决方案2】:

    我使用validator 进行输入卫生,它可以以非常酷的方式使用。

    安装它,然后像这样使用它:

    import { isEmail } from 'validator';
    // ... 
    
    const EmailSchema = new Schema({
        email: { 
            //... other setup
            validate: [ isEmail, 'invalid email' ]
        }
    });
    

    工作愉快,读起来很好。

    【讨论】:

    • 对于 ES5 :) , const validator = require('validator');验证:[validator.isEmail,'无效的电子邮件'],
    • const 不幸在 ES5 中不可用。
    • 带有import isEmail from 'validator/lib/isEmail';的小夹头
    【解决方案3】:

    您可以使用正则表达式。看看这个问题:Validate email address in JavaScript?

    我以前用过这个。

    UserSchema.path('email').validate(function (email) {
       var emailRegex = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
       return emailRegex.test(email.text); // Assuming email has a text attribute
    }, 'The e-mail field cannot be empty.')
    

    【讨论】:

    • 太棒了!我也不知道 test() 方法。
    • 您应该在函数外部定义正则表达式以获得更好的性能。
    • 此正则表达式无法验证某些有效的电子邮件,例如左侧包含加号的电子邮件。
    • 不禁注意到结尾部分,是 2-4 个字符之间的任何单词吗?这是否意味着 info@company.london 之类的电子邮件不起作用?正则表达式可能是错误的。
    • @Val 这些顶级域名早在 2013 年就不存在了。查看this answer 以获取最新的正则表达式
    【解决方案4】:

    validator 不能很好地与 mongoose 一起摆脱将 isAsync 设置为 false 的警告

    const validator = require('validator');
    
    email:{
    type:String,
    validate:{
          validator: validator.isEmail,
          message: '{VALUE} is not a valid email',
          isAsync: false
        }
    }
    

    【讨论】:

    • 没有 isAsync: false ,验证在我的情况下不起作用,我使用的是带有承诺的猫鼬。猫鼬版5.2.13
    【解决方案5】:

    我知道这是旧的,但我没有看到这个解决方案所以想我会分享:

    const schema = new mongoose.Schema({
        email: {
            type: String,
            trim: true,
            lowercase: true,
            unique: true,
            validate: {
                validator: function(v) {
                    return /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(v);
                },
                message: "Please enter a valid email"
            },
            required: [true, "Email required"]
        }
    });
    

    您可以对任何要验证的类型执行此操作,只需传递适当的正则表达式即可。如果您搜索要验证的类型及其相关的正则表达式,则很容易找到解决方案。这将使您的验证保持一致,并将所有代码放在架构中,而不是挂起函数。

    【讨论】:

    • 非常经典的解决方案。你能解释一下unique键的工作原理吗
    • @HidaytRahman mongoose 将不会创建另一个包含该电子邮件的文档
    【解决方案6】:

    出于某种原因,validate: [ isEmail, 'Invalid email.'] 不能很好地配合 validate() 测试。

    const user = new User({ email: 'invalid' });
    try {
      const isValid = await user.validate();
    } catch(error) {
      expect(error.errors.email).to.exist; // ... it never gets to that point.
    }
    

    但是 mongoose 4.x(它也可能适用于旧版本)还有其他与单元测试配合使用的替代选项。

    单一验证器:

    email: {
      type: String,
      validate: {
        validator: function(value) {
          return value === 'correct@example.com';
        },
        message: 'Invalid email.',
      },
    },
    

    多个验证器:

    email: {
      type: String,
      validate: [
        { validator: function(value) { return value === 'handsome@example.com'; }, msg: 'Email is not handsome.' },
        { validator: function(value) { return value === 'awesome@example.com'; }, msg: 'Email is not awesome.' },
      ],
    },
    

    如何验证电子邮件:

    我的建议:留给已经投入数百小时构建适当验证工具的专家。 (也已在here 中回答)

    npm install --save-dev validator

    import { isEmail } from 'validator';
    ...
    validate: { validator: isEmail , message: 'Invalid email.' }
    

    【讨论】:

      【解决方案7】:

      架构的电子邮件类型 - mongoose-type-email

      var mongoose = require('mongoose');
      require('mongoose-type-email');
      
      var UserSchema = new mongoose.Schema({
          email: mongoose.SchemaTypes.Email
      });
      

      可能的参考:

      【讨论】:

        【解决方案8】:
        email: {
            type: String,
            match: [/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/, `Please fill valid email address`],
            validate: {
              validator: function() {
                return new Promise((res, rej) =>{
                  User.findOne({email: this.email, _id: {$ne: this._id}})
                      .then(data => {
                          if(data) {
                              res(false)
                          } else {
                              res(true)
                          }
                      })
                      .catch(err => {
                          res(false)
                      })
                })
              }, message: 'Email Already Taken'
            }
          }
        

        【讨论】:

        • 不推荐这种方法。当您定义 User 架构并且在声明架构之前使用 User.findOne 时。
        猜你喜欢
        • 2020-03-12
        • 2021-06-25
        • 2019-01-10
        • 2016-01-22
        • 2017-11-28
        • 1970-01-01
        • 2014-04-15
        • 1970-01-01
        相关资源
        最近更新 更多