express-validator封装为独立中间件后校验不生效该如何处理?
问题根源
你目前的校验逻辑不生效的核心原因是:body() 方法返回的本身就是一个Express中间件函数,你在自定义的validateRequest中仅完成了校验规则的构造,没有实际执行这些校验中间件的逻辑,因此校验流程根本没有运行,自然无法捕获到错误信息。
同时你当前编写的密码一致性校验规则本身存在问题:equals('confirmPassword')的作用是校验password字段的值等于confirmPassword这个固定字符串,而非等于请求体中confirmPassword字段的值,即使直接写在路由中也无法达到预期的密码比对效果。
正确的抽离实现方案
你完全不需要把所有校验规则都堆在路由文件中,以下是两种常用的分层抽离方案:
方案1:单独抽离校验规则数组(官方推荐)
将不同接口的校验规则统一放在独立的校验模块中管理,路由直接引入使用即可,既避免路由文件臃肿,也符合express-validator的设计逻辑。
- 新建独立校验文件,例如
src/validators/auth.js:
const { body } = require('express-validator'); // 注册接口校验规则 exports.signupValidation = [ body('email') .isEmail() .withMessage('Please enter a valid email'), // 实现密码和confirmPassword字段比对+条件校验 body('password') // 只有请求体存在password_confirm字段时才执行后续校验 .if(body('password_confirm').exists()) .custom((value, { req }) => { if (value !== req.body.confirmPassword) { throw new Error('Passwords do not match'); } return true; }) ];
- 路由文件中引入使用:
const { signupValidation } = require('./validators/auth'); router.post( '/signup', signupValidation, // 直接引入校验规则数组 userController.hashPassword, userController.signup );
- 控制器中还是按照你原来的写法用
validationResult收集错误即可。
方案2:封装为全链路校验中间件
如果你希望把校验执行、错误收集、错误返回的逻辑全部封装在独立中间件中,不需要控制器再处理错误判断,可以用run方法手动执行校验规则:
const { body, validationResult } = require('express-validator'); exports.validateSignupRequest = async (req, res, next) => { // 构造校验规则 const validations = [ body('email').isEmail().withMessage('Please enter a valid email'), body('password') .if(body('password_confirm').exists()) .custom((value, { req }) => { if (value !== req.body.confirmPassword) { throw new Error('Passwords do not match'); } return true; }) ]; // 手动执行所有校验规则 await Promise.all(validations.map(validation => validation.run(req))); // 收集校验错误,有错误直接返回 const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } // 校验通过进入下一个中间件 next(); };
路由直接使用该中间件即可,控制器无需再做错误判断:
router.post( '/signup', userController.validateSignupRequest, userController.hashPassword, userController.signup );
内容的提问来源于stack exchange,提问作者Ahsan Danish
相关产品推荐
相关产品推荐

