Mongoose手机号min数字验证插入数据失效的原因与解决方法
问题:Mongoose中手机号验证规则不生效的原因及解决方法
我正在使用Node、Express和Mongoose,通过POST方法向MongoDB插入数据。为phone字段设置了验证规则,要求其至少包含10位数字,否则抛出验证错误,但实际插入数据时,即使phone字段长度不足10位仍能成功保存。
相关代码
Mongoose模型
const mongoose = require('mongoose'); const validator = require('validator'); const schema = new mongoose.Schema({ name: { type: String, required: true, minLength: [2, 'Name should contain at least two characters!'], trim: true }, email: { type: String, required: true, trim: true, validate(value) { if (!validator.isEmail(value)) throw new Error('Invalid email!'); } }, phone: { type: Number, required: true, min: [10, 'Phone number should contain at least ten digits!'], trim: true }, message: { type: String, required: true, minLength: [3, 'Message should contain at least three characters!'], trim: true }, date: { type: Date, required: true, default: Date.now } }); const RdwMessage = new mongoose.model('RdwMessage', schema); module.exports = RdwMessage;
POST路由
app.post('/contact', async (req, res) => { try { const doc = new RdwMessage(req.body); await doc.save(); res.status(201).render('index'); } catch (error) { res.status(404).send(`Failed to submit message with the following error: ${error}`); } });
原因分析
核心问题出在phone字段的类型与验证规则不匹配:
- 字段类型错误:手机号本质是字符串(无需数值运算,且可能包含开头0、国际区号等非数字字符),设为
Number类型会引发两个问题:- 开头的0会被自动丢弃(比如
0123456789会被存为123456789) - 超长手机号可能触发数值溢出,无法正确存储
- 开头的0会被自动丢弃(比如
- 验证规则错误:
min规则对Number类型是判断数值大小,而非数字位数。比如123是数值123,大于10,所以会通过验证,但它只有3位数字,不符合需求。
解决方法
修改phone字段为String类型,并搭配正确的验证规则:
方案一:用minLength/maxLength限制位数+纯数字验证
phone: { type: String, required: true, minLength: [10, 'Phone number should contain at least ten digits!'], maxLength: [15, 'Phone number cannot exceed 15 digits!'], trim: true, validate(value) { if (!validator.isNumeric(value)) { throw new Error('Phone number must contain only digits!'); } } }
方案二:自定义正则验证(更灵活)
phone: { type: String, required: true, trim: true, validate(value) { // 匹配10-15位纯数字,若支持国际区号可改为/^\+?\d{10,15}$/ const phoneRegex = /^\d{10,15}$/; if (!phoneRegex.test(value)) { throw new Error('Phone number should contain 10 to 15 digits!'); } } }
额外提示
若需支持国际手机号(如带+前缀),可以使用validator库的isMobilePhone方法做精准验证:
validate(value) { // 指定支持的国家代码,比如印度、美国 if (!validator.isMobilePhone(value, ['en-IN', 'en-US'])) { throw new Error('Invalid phone number!'); } }
内容的提问来源于stack exchange,提问作者priyamtheone
相关产品推荐
相关产品推荐

