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

Node.js用户验证模块控制器'res is not defined'错误解决

解决'res is not defined'错误及优化验证逻辑

你的问题根源在于验证函数的作用域中没有res变量:res是Express控制器请求处理函数的参数,仅在users函数内部可用,但你在common.js的验证函数里直接调用res.status(),导致运行时找不到res。

更合理的做法是让验证函数只专注于逻辑判断,返回错误信息(或null表示验证通过),由控制器统一处理HTTP响应。这样既解耦了验证逻辑和响应逻辑,也彻底解决了res未定义的问题。

修改后的代码实现

1. 重构common.js的验证函数

让每个验证函数返回错误对象(包含状态码和提示信息),验证通过则返回null:

const user = require('../models/user');

module.exports = {
    verifyEmail: async(email) => {
        if (!email) {
            return { status: 404, message: 'Email is required' };
        }
        const regex = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
        if (!email.match(regex)) {
            return { status: 400, message: 'invalid email address' };
        }
        const existingUser = await user.findOne({ email });
        if (existingUser) {
            return { status: 400, message: 'User already exists' };
        }
        return null;
    },
    verifyFirstName: (firstName) => {
        if (!firstName) {
            return { status: 404, message: 'First name is required' };
        }
        if (firstName.length < 3 || firstName.length > 20) {
            return { status: 411, message: 'length must be between 3 and 20 characters' };
        }
        return null;
    },
    verifyLastName: (lastName) => {
        if (!lastName) {
            return { status: 404, message: 'Last name is required' }; // 修正原代码的提示错误
        }
        if (lastName.length < 3 || lastName.length > 20) {
            return { status: 411, message: 'length must be between 3 and 20 characters' };
        }
        return null;
    },
    verifyPassword: (password, confirmPassword) => {
        if (!password) {
            return { status: 404, message: 'Password field is required' };
        }
        if (password.length < 5) {
            return { status: 411, message: 'Password is too short' };
        }
        const passRegex = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?!.*\s).{5,15}$/;
        if (!password.match(passRegex)) {
            return { status: 400, message: 'Password must include at least one lowercase letter, one uppercase letter, one digit, and one special character' };
        }
        if (password !== confirmPassword) {
            return { status: 417, message: 'passwords do not match' };
        }
        return null;
    },
    verifyPhone: (phoneNumber) => {
        if (!phoneNumber) {
            return { status: 404, message: 'Phone number is required' };
        }
        const phoneRegex = /^\+?\d{1,4}?[-.\s]?\(?\d{1,3}?\)?[-.\s]?\d{1,4}[-.\s]?\d{1,4}[-.\s]?\d{1,9}$/;
        if (!phoneNumber.match(phoneRegex)) {
            return { status: 400, message: 'Please add a valid phone number' };
        }
        return null;
    }
}

2. 修改controller.js处理验证结果

在控制器中调用验证函数,检查返回值,有错误则立即返回响应;验证通过后再执行用户创建逻辑:

const verifier = require('./common'); // 路径根据实际项目调整
const bcrypt = require('bcrypt');
const user = require('../models/user');

module.exports.users = async(req, res) => {
    try {
        const { email, firstName, lastName, password, confirmPassword, phoneNumber } = req.body;

        // 逐个验证,遇到错误立即返回
        const emailError = await verifier.verifyEmail(email);
        if (emailError) {
            return res.status(emailError.status).json({ message: emailError.message });
        }

        const firstNameError = verifier.verifyFirstName(firstName);
        if (firstNameError) {
            return res.status(firstNameError.status).json({ message: firstNameError.message });
        }

        const lastNameError = verifier.verifyLastName(lastName);
        if (lastNameError) {
            return res.status(lastNameError.status).json({ message: lastNameError.message });
        }

        const passwordError = verifier.verifyPassword(password, confirmPassword);
        if (passwordError) {
            return res.status(passwordError.status).json({ message: passwordError.message });
        }

        const phoneError = verifier.verifyPhone(phoneNumber);
        if (phoneError) {
            return res.status(phoneError.status).json({ message: phoneError.message });
        }

        // 创建用户实例
        const newUser = new user({
            firstName,
            lastName,
            password,
            phone: phoneNumber
        });

        // 改用async/await处理bcrypt哈希(避免回调混用async/await的问题)
        const salt = await bcrypt.genSalt(10);
        newUser.password = await bcrypt.hash(newUser.password, salt);
        
        await newUser.save();
        return res.status(201).json({ message: 'User created successfully', user: newUser });

    } catch (err) {
        return res.status(500).json({ message: 'Server error', error: err.message });
    }
}

额外修正的问题

  1. 原verifyLastName函数中错误提示写成了"First name is required",已修正为"Last name is required";
  2. 原代码中bcrypt回调混用async/await可能导致密码哈希未完成就保存用户,改用纯async/await写法;
  3. 修正了变量名混淆问题(User和user),提升代码可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 17:30:55