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 中一致。


参考文档

本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台