express-validator 实战:Express 数据校验完全指南
express-validator 基于 validator.js 提供声明式校验链。本文讲解校验规则编写、sanitize 清洗、错误收集与统一响应格式,以及自定义校验器与异步校验。
express-validator 用链式中间件声明校验规则:body('email').isEmail() 写在路由前,validationResult(req) 收集错误返回 400。校验与清洗(sanitization)一体完成,是 Express 请求数据防线的标准件。
为什么校验必须在入口处做
用户输入永远不可信:类型错误、注入载荷、超长字段——让脏数据穿过控制器进入业务层,bug 和安全问题就会遍地开花。express-validator 把校验规则钉在路由定义上,数据进门之前先过安检。
安装与基本用法
npm install express-validator
const { body, param, query, validationResult } = require('express-validator');
app.post('/users',
body('name').trim().notEmpty().withMessage('姓名必填')
.isLength({ max: 50 }).withMessage('姓名过长'),
body('email').isEmail().normalizeEmail().withMessage('邮箱格式错误'),
body('age').optional().isInt({ min: 0, max: 150 }).toInt(),
(req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
// 校验通过,req.body 已是清洗后的数据
}
);
链上的每个方法都是一条规则;withMessage 定制中文提示;trim/normalizeEmail/toInt 这类 sanitize 方法顺手把数据清洗干净。
校验位置与规则体系
body('field')/param('id')/query('q')/header('x-token'):按数据来源校验;- 常用规则:
isInt/isFloat/isBoolean、isLength、matches(/正则/)、isIn(['a','b'])、isISO8601()(日期)、isURL/isUUID; optional():字段可缺席,但出现就必须合法;optional({ values: 'falsy' })连空字符串也放行。
自定义与异步校验
body('username').custom(async (username) => {
const exists = await db.user.findByUsername(username);
if (exists) throw new Error('用户名已被占用');
});
body('password').custom((value, { req }) => {
if (value !== req.body.confirmPassword) {
throw new Error('两次密码不一致');
}
return true;
});
custom 支持异步(数据库唯一性检查)与跨字段访问({ req }),覆盖复杂业务规则。
错误处理的统一封装
每个路由重复写 validationResult 太啰嗦,抽成中间件:
const validate = (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({
code: 'VALIDATION_FAILED',
fields: Object.fromEntries(
errors.array().map(e => [e.path, e.msg])
),
});
}
next();
};
app.post('/users', [nameRule, emailRule], validate, handler);
规则数组 + validate + handler 的三段式,路由声明即校验文档。配合 matchedData(req) 只取校验过的字段,彻底杜绝参数污染。
常见问题(FAQ)
Q:express-validator 和 Joi/Zod 怎么选?
express-validator 与 Express 中间件模型贴合最紧,规则写在路由上;Joi/Zod 是独立 Schema 库(Zod 还能推导 TS 类型)。Express 传统项目用 express-validator 最顺;TypeScript 全栈新项目建议直接 Zod(类型贯通前后端)。
Q:文件上传怎么校验?
express-validator 管文本字段;文件校验(类型、大小)在 multer 的 fileFilter 与 limits 中做,两者互补。校验文件内容(如图片尺寸)在业务层处理。
Q:校验失败返回 400 还是 422?
语义上 422(Unprocessable Entity)更精确表达"格式合法但语义校验失败";400 也被广泛使用。团队统一即可——重要的是状态码策略在整个 API 中一致。
参考文档
本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。