- 后端
【免费下载链接】express-validator
An express.js middleware for validator.js.
express-validator 是一组包装 validator.js 校验与清洗函数的 Express.js 中间件,用于在请求进入业务逻辑之前统一完成输入校验与数据清洗。本指南将带你在一个真实的 Express 应用中从零开始接入校验链、读取验证结果并返回标准化的错误响应,同时结合仓库源码解释其底层工作机制。
express-validator 是什么
express-validator 的本质是一组 express.js 中间件,它将 validator.js 中丰富的校验器(validator)与清洗器(sanitizer)函数包装成可以在路由中链式调用的形式。你既可以对请求的任意字段逐个校验,也可以把多个校验组合成一条“校验链”(validation chain),并用内置的工具判断请求是否合法、哪些数据被匹配到了。
从仓库的 package.json 可以看出,express-validator 的运行时依赖只有两个:lodash和validator(当前锁定在~13.15.35),这说明它自身并不重复造轮子,而是把 validator.js 的函数能力与 Express 的中间件模型做了深度结合。包入口 src/index.ts 统一导出了body、check、query、validationResult、matchedData、checkSchema、oneOf等全部核心 API。
环境要求与安装
原版 6.7.0 文档要求你的环境具备 Node.js 8 或更新的版本,使用 npm 即可完成安装:
npm install --save express-validator需要说明的是,当前仓库的 package.json 中engines字段标注为"node": ">= 14.0.0",也就是说仓库最新版本(7.3.2)对运行环境的要求已经提升到 Node.js 14 及以上,这是 6.x 到 7.x 演进过程中的一个关键变化。安装完成并重启应用后,即可在代码中通过require('express-validator')或 ES Module 的import { ... } from 'express-validator'引入所需 API。
第一步:先写一个基本的 Express 路由
为了让校验有意义,我们先写一个向数据库创建用户的 Express 路由。这一步不需要任何 express-validator 的参与,只是后续验证的“靶场”:
const express = require('express'); const app = express(); app.use(express.json()); app.post('/user', (req, res) => { User.create({ username: req.body.username, password: req.body.password }).then(user => res.json(user)); });建议:继续阅读本指南前,最好对 express.js 模块有基本了解,至少知道中间件、
req.body和路由参数是如何工作的。
第二步:用校验链为输入加上约束
上面的路由目前对任何输入都会照单全收。接下来我们引入body和validationResult,在创建用户之前先校验输入,并把错误收集起来统一上报:
// ...rest of the initial code omitted for simplicity. const { body, validationResult } = require('express-validator'); app.post('/user', [ // username must be an email body('username').isEmail(), // password must be at least 5 chars long body('password').isLength({ min: 5 }) ], (req, res) => { // Finds the validation errors in this request and wraps them in an object with handy functions const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } User.create({ username: req.body.username, password: req.body.password }).then(user => res.json(user)); });这段代码揭示了 express-validator 的核心使用模式:
body('username')声明“我要从req.body中取出名为username的字段”;.isEmail()、.isLength({ min: 5 })来自 validator.js,是被包装后的标准校验器;- 整条
body('username').isEmail()就是一个校验链(ValidationChain),它本身可以作为中间件放进路由的中间件数组中。
校验链从哪来:五个位置构建器
body并不是唯一的入口。查看 src/middlewares/validation-chain-builders.ts 可以看到,buildCheckFunction(locations)是底层工厂函数,check、body、cookie、header、param、query六个公开 API 都是它的特定实例化:
| API | 校验的位置(Location) | 用途 |
|---|---|---|
check(fields) | body、cookies、headers、params、query | 在全部请求位置中查找字段 |
body(fields) | body | 只校验req.body |
cookie(fields) | cookies | 只校验解析后的 Cookie 对象 |
header(fields) | headers | 只校验请求头 |
param(fields) | params | 只校验路径参数(如/user/:id中的id) |
query(fields) | query | 只校验查询字符串参数 |
fields参数可以是单个字段名字符串,也可以是字符串数组,用于一次声明多个字段。这样设计的好处是同一套校验语法可以在五个请求位置上完全复用,比如query('keyword').isLength({ min: 1 })与body('keyword').isLength({ min: 1 })的写法完全一致。
校验链的底层实现
在 src/middlewares/check.ts 中可以看到check()的完整实现:它先用ContextBuilder构建一个“上下文”(记录字段、位置、默认错误消息),再通过ContextRunnerImpl得到运行时执行器,最后把执行器、校验器实现(ValidatorsImpl)、清洗器实现(SanitizersImpl)和上下文处理器(ContextHandlerImpl)全部绑定到同一个中间件函数上返回。换句话说,校验链本身就是一个 Express 中间件函数,同时它又携带了.isEmail()、.trim()、.custom()等一整套可链式调用的方法。
第三步:处理验证错误并返回响应
调用validationResult(req)会返回一个Result实例,它封装了当前请求中所有校验上下文收集到的错误。上面的示例通过errors.isEmpty()判断是否合法,并用errors.array()输出错误数组、以 400 状态码响应。Voila!此后只要请求中带有非法的username或password,服务器就会返回如下结构的 JSON:
{ "errors": [{ "location": "body", "msg": "Invalid value", "param": "username" }] }这个错误对象的三个字段含义分别是:
location:错误字段所在的请求位置(这里是body);msg:错误消息,默认是Invalid value;param:出错的字段名(这里是username)。
Result 对象的完整能力
在 src/validation-result.ts 中,Result类提供了几个开箱即用的方法,它们都是这个“错误包装对象”的 handy functions:
isEmpty():返回true表示没有任何校验错误;array(options?):把错误按格式化函数转换后返回数组,传入{ onlyFirstError: true }可以让每个字段只保留第一条错误;mapped():返回“字段名 → 错误”的对象映射,同一字段的多条错误只保留第一条;formatWith(formatter):返回一个使用自定义格式化函数的新Result实例;throw():若存在错误则抛出一个携带同样方法的异常,适合在非中间件场景(如手动运行校验)中使用。
此外,validationResult还带有一个withDefaults静态属性,用于创建带默认错误格式化器的自定义结果工厂。
关于 7.x 的错误结构变化
上面展示的是 6.7.0 文档中的错误格式(字段名param、无type字段)。当前仓库(7.3.2)的 src/base.ts 中,FieldValidationError已经演化为包含type: 'field'、path、location、value、msg的结构,其中path取代了原来的param,type用于区分普通字段错误、oneOf备选错误、checkExact未知字段错误等不同来源。如果你基于 7.x 使用,实际返回的错误会形如:
{ "errors": [ { "type": "field", "location": "query", "path": "person", "msg": "Invalid value" } ] }请求对象要求与可替换的框架
express-validator 对请求对象的建模要求与 Express 一致:req.body、req.cookies、req.headers、req.params、req.query五个属性(见 src/base.ts 中的Request接口与Location类型)。因此,尽管名字里有 express,它同样可以用于请求模型与 Express 类似的其它 HTTP 框架,例如 Restify。只要目标框架的请求对象包含上述属性,接入方式就与 Express 完全一致。
继续深入:进阶主题
本指南覆盖了 express-validator 的核心工作流:安装 → 声明校验链 → 提取结果 → 返回错误。接下来可以沿着 6.7.0 文档给出的进阶路径继续深入:
- 输入清洗(Sanitization):了解
trim()、escape()等清洗器如何与校验器协同,从源头降低 XSS 等注入风险; - 自定义校验器与清洗器:用
custom()与customSanitizer()扩展业务相关的校验逻辑; - 自定义错误消息:为每个校验器定制面向用户的提示文案;
- 通配符(Wildcards):用
*.与**选择嵌套对象和数组中的字段; - Schema 校验:用
checkSchema()以声明式对象统一描述所有字段的校验规则。
如果想了解与 6.7.0 略有差异的最新 API 形态,还可以对照仓库当前的 docs/guides/getting-started.md(其中包含完整的 JavaScript / TypeScript 双版本示例)、docs/guides/validation-chain.md 与 docs/guides/field-selection.md,并结合 src/chain/validators.ts、src/chain/sanitizers.ts 查看每个内置校验器与清洗器的签名和默认参数。
- 后端
【免费下载链接】express-validator
An express.js middleware for validator.js.
相关推荐
express-validator 快速上手:为 Express 请求接入 validator.js 校验与清洗中间件
express validator 快速上手:为 Express 请求接入 validator.js 校验与清洗中间件 express validator 是一
后端express-validator 快速入门:在 Express.js 中为请求添加校验与清洗中间件
express validator 快速入门:在 Express.js 中为请求添加校验与清洗中间件 express validator 是一组封装了 vali
后端AgentOps Instrumentation Common 模块深度解析:WrapConfig、Attribute Handler 与 OpenTelemetry 方法包装机制
AgentOps Instrumentation Common 模块深度解析:WrapConfig、Attribute Handler 与 OpenTeleme
后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考