Node.js注册API如何实现邮箱、手机号、地址等字段的合法校验?
邮箱、手机号、地址字段校验实现方法
方案1:Mongoose Schema 层校验(耦合度低,推荐优先使用)
你当前用的是Mongoose的Schema定义数据结构,可以直接在Schema中添加校验规则,数据写入时会自动触发校验,不符合规则会直接抛出错误。
修改后的userModels.js代码如下:
// 注意原拼写错误:Shema 修正为 Schema const UserSchema = new Schema({ name: { type: String, required: [true, '用户名不能为空'], maxlength: [20, '用户名不能超过20个字符'] }, date_of_birth: { type: Date, required: [true, '出生日期不能为空'] }, address: { type: String, required: [true, '地址不能为空'], minlength: [5, '地址长度不能少于5个字符'], maxlength: [100, '地址长度不能超过100个字符'] }, phone: { type: String, required: [true, '手机号不能为空'], // 国内手机号正则校验 match: [/^1[3-9]\d{9}$/, '请输入合法的11位国内手机号'] }, email: { type: String, required: [true, '邮箱不能为空'], // 邮箱格式正则校验 match: [/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, '请输入合法的邮箱地址'], // 直接在Schema层加唯一索引,避免重复插入,比代码层面判断更可靠 unique: [true, '该邮箱已注册'] }, password: { type: String, required: [true, '密码不能为空'] } }, { collection: 'users' });
启用这个校验后,调用User.create时如果字段不符合规则,会直接抛出包含错误提示的异常,你可以在catch块中捕获并返回给前端。
方案2:Controller 层前置校验(性能更高,可提前拦截非法请求)
在请求进入数据库操作之前先做参数校验,不需要访问数据库就能直接返回错误,响应速度更快。
修改后的userController.js代码如下:
// 预先定义校验正则 const EMAIL_REG = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ const PHONE_REG = /^1[3-9]\d{9}$/ exports.register = async (req, res, next)=>{ try { const { email, password, name, address, phone, date_of_birth } = req.body // 非空校验 if (!email || !password || !name || !address || !phone || !date_of_birth) { return res.status(400).json({message: "所有必填字段不能为空"}); } // 邮箱格式校验 if (!EMAIL_REG.test(email)) { return res.status(400).json({message: "请输入合法的邮箱地址"}); } // 手机号格式校验 if (!PHONE_REG.test(phone)) { return res.status(400).json({message: "请输入合法的11位手机号"}); } // 地址长度校验 if (address.length <5 || address.length >100) { return res.status(400).json({message: "地址长度需要在5-100字符之间"}); } // 原拼写错误:findUserResgiter 修正为 findUserRegister const data = await userService.findUserRegister(email); if(data === null){ // 注意:不要用MD5加密密码,安全性极低,建议替换为bcrypt做哈希存储 await User.create({ name, email, password: md5(password), address, date_of_birth, phone }) return res.status(200).json({message: "注册成功"}); }else{ return res.status(401).json({message: "该邮箱已注册"}); } } catch (e) { // 不要留空catch块吞错误,需要捕获异常返回 return res.status(500).json({message: "服务端错误", error: e.message}) } };
额外优化建议
- 不要再使用MD5存储密码,极易被破解,建议替换为bcrypt等慢哈希算法做密码加密
- 原代码中存在多处拼写错误:Schema写成Shema、register写成resgiter,建议修正避免功能异常
- 不要留空的catch块,异常不处理会导致排查问题难度大幅提升
内容的提问来源于stack exchange,提问作者MaditionSky
相关产品推荐
相关产品推荐

