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

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字段的类型与验证规则不匹配:

  1. 字段类型错误:手机号本质是字符串(无需数值运算,且可能包含开头0、国际区号等非数字字符),设为Number类型会引发两个问题:
    • 开头的0会被自动丢弃(比如0123456789会被存为123456789)
    • 超长手机号可能触发数值溢出,无法正确存储
  2. 验证规则错误: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 02:10:49