Express中自动匹配POST请求验证器的执行问题求助
问题:express-validator 动态验证中间件无法执行的解决思路
场景与现有实现
我正在使用express-validator,想要实现一个适配所有POST请求的中间件——根据请求路径自动匹配对应验证器并调用相应验证方法,规则如下:
- 验证器存于
/validators文件夹,文件名与请求路径第一级对应(例如POST/auth/checkSignup对应/validators/auth.js) - 每个验证器对象包含一个或多个以
check开头的方法,方法名的动作部分来自请求路径(例如/auth/checkSignup对应AuthValidator里的checkSignup方法)
当前app.js调用方式
app.post( '*', ValidationDispatcher.validationMiddleware );
现有中间件实现
validationMiddleware: (req, res, next) => { try { const pathSections = req.path.split("/"); const base = pathSections.length > 1 ? pathSections[1] : null; const action = pathSections.length > 2 ? pathSections[2] : null; if (base) { const validator = require(`./${base}`); let method = "check"; if (action) { method += action.charAt(0).toUpperCase() + action.slice(1); } return validator[method](); } } catch (error) { console.log(error); } }
验证方法示例
checkSignup() { return expressValidator.checkSchema({ email: { ...this.baseEmailSchema, custom: { options: (value) => { return UsersController.getByEmail(value).then((res) => { return res != null; }); }, errorMessage: "user with this email already exists", }, }, password: this.basePasswordSchema, confirmPassword: { custom: { options: (value, { req }) => { return value === req.body.password; }, errorMessage: "passwords have to match", }, }, }); }
现在遇到的问题是:返回的验证中间件无法执行,求解决思路。
解决思路与修正方案
1. 核心问题:未正确执行验证中间件
express中间件的核心逻辑是必须调用next()传递控制权,或直接处理响应。你当前的代码直接返回了checkSchema生成的中间件函数,但没有传入req、res、next参数去执行它。
修正后的中间件代码:
validationMiddleware: (req, res, next) => { try { const pathSections = req.path.split("/"); const base = pathSections.length > 1 ? pathSections[1] : null; const action = pathSections.length > 2 ? pathSections[2] : null; if (base) { // 修正路径:确保能正确定位到validators文件夹下的文件,根据项目结构调整相对路径 const validatorPath = require.resolve(`./validators/${base}`); // 可选:清除模块缓存,支持热加载验证器文件 delete require.cache[validatorPath]; const validator = require(validatorPath); // 修正方法名映射逻辑:根据实际路径规则调整 // 示例:如果路径是/auth/signup,对应checkSignup方法 let method = "check"; if (action) { method += action.charAt(0).toUpperCase() + action.slice(1); } // 检查方法是否存在再执行 if (typeof validator[method] === 'function') { const validationChain = validator[method](); // 执行验证中间件,传入req、res、next return validationChain(req, res, next); } } // 无对应验证逻辑时,直接进入下一个中间件 next(); } catch (error) { console.error('验证中间件错误:', error); // 将错误传递给express全局错误处理中间件 next(error); } }
2. 修正路径到方法名的映射逻辑
原代码存在逻辑错误:如果请求路径是/auth/checkSignup,action为checkSignup,拼接后会得到checkCheckSignup,与实际验证方法checkSignup不符。需根据你的路径规则调整:
- 若路径规则为
/[base]/signup对应checkSignup:保持原拼接逻辑 - 若路径规则为
/[base]/checkSignup对应checkSignup:直接将action作为方法名,无需拼接check前缀
3. 处理this指向问题
验证方法中使用了this.baseEmailSchema,如果验证器是类实例导出,直接调用validator[method]()会丢失this指向,可通过两种方式解决:
- 调用方法时绑定
this:const validationChain = validator[method].call(validator); - 用箭头函数定义验证方法,避免
this丢失:checkSignup = () => { return expressValidator.checkSchema({...}); }
4. 完善错误处理
原代码仅打印错误但未处理,会导致请求挂起。需调用next(error)将错误传递给express全局错误处理中间件,或直接返回错误响应。
内容的提问来源于stack exchange,提问作者Natalia Guerrini
相关产品推荐
相关产品推荐

