实战指南:直接校验字符串、数组与数字类型的 req.body)
后端【免费下载链接】express-validatorAn express.js middleware for validator.js.项目地址https://gitcode.com/gh_mirrors/ex/express-validator点击查看免费下载导读本文聚焦 express-validator 中一个常被忽视但非常实用的能力全量请求体验证Whole Body Validation。当你面对的不是标准 JSON 对象、而是字符串、数组甚至数字形式的请求体时可以直接省略字段路径把整个req.body作为验证与清洗目标。文章以 v5.2.0 文档为基础结合仓库中docs/guides/field-selection.md的字段选择语法与src/field-selection.ts的底层实现为你讲清原理、给出可复制的代码与 HTTP 示例并延伸到全量选择在其他请求位置req.cookies、req.params、req.query、req.headers的应用方式帮助你写出既能覆盖整块数据、又能精准命中嵌套字段的健壮验证中间件。何时需要全量请求体验证express-validator 的常规用法是面向对象化请求体做字段级验证例如body(email).isEmail()。但在真实业务里请求体并不总是 JSON 对象文本型接口密码找回、短信/邮件验证码等接口常以text/plain发送原始字符串请求体就是一个裸字符串批量型接口数组本身就是请求体的核心内容需要整体校验如批量更新 ID 列表、数组型标签集合数值型接口请求体可能直接是数字比如上报心跳间隔、经纬度坐标等。当请求体的根就是待验证的数据时为它硬套一个字段名毫无意义——这时就应该省略字段参数直接对整个req.body执行验证与清洗。v5.2.0 文档website/versioned_docs/version-5.2.0/feature-whole-body-validation.md开篇即点明这一场景Sometimes you need to validate requests whose body is a string, an array, or even a number!有时你需要验证请求体是字符串、数组甚至数字的请求省略字段参数body() 直接作用于 req.body经典文本请求体示例以下代码来自 v5.2.0 原文档演示了对text/plain文本请求体直接做isEmail()验证的完整配置const bodyParser require(body-parser); const express require(express); const { body } require(express-validator/check); const app express(); // Will handle text/plain requests app.use(bodyParser.text()); app.post(/recover-password, body().isEmail(), (req, res) { // Assume the validity of the request was already checked User.recoverPassword(req.body).then(() { res.send(Password recovered!); }); });该配置能够正确处理如下原始 HTTP 请求POST /recover-password HTTP/1.1 Host: localhost:3000 Content-Type: text/plain myemail.com逐行拆解这个示例app.use(bodyParser.text())express.json()只解析application/json无法把text/plain解析成req.body对象因此这里必须先用body-parser的text()中间件把文本请求体挂到req.body上body()body链构造函数来自express-validator/check调用时不传字段参数。从源码看check()的字段参数默认值是空字符串见src/middlewares/check.ts#L12-L16export function check(fields: string | string[] , ...): ValidationChain所以body()与body()在语义上等价都表示选中整个req.bodybody().isEmail()isEmail()直接作用于req.body这个字符串上验证通过后req.body即为myemail.comUser.recoverPassword(req.body)业务处理器拿到的是被验证过的原始字符串可以直接使用。需要特别说明express-validator 只负责验证并记录结果不会自动中断请求或返回错误响应。上例中的Assume the validity of the request was already checked注释意味着在实际项目中你应该在处理器内用validationResult(req)检查验证结果失败时提前返回错误详见 getting-started.md 的Handling validation errors一节。为什么不传参数与传空字符串等价在字段选择层面全量选择有两条等价写法出自docs/guides/field-selection.md的 Whole-body selection 小节app.post( /recover-password, // These are equivalent. body().isEmail(), body().isEmail(), (req, res) { // Handle request }, );从实现角度可以更精确地理解全量选择selectFields()见src/field-selection.ts#L10-L21会依次展开每个字段路径对应的请求位置在expandField()src/field-selection.ts#L27-L43中当展开后的路径为空字符串时取值逻辑是const value path ? req[location] : _.get(req[location], path);——路径为空时直接返回整个req[location]对象对body()而言即整个req.body因此body().isEmail()与body().isEmail()产生完全相同的FieldInstancepath: 、location: body、value: req.body。全量选择不限于 body其他请求位置也能整块校验docs/guides/field-selection.md的全量选择小节有一条重要提示Its possible to select the wholereq.cookies,req.paramsand etc too, though its probably not as useful or common as itd be withreq.body.也就是说省略字段 选择整个位置的机制对req.cookies、req.params、req.query、req.headers同样成立。这与链构造函数的设计一一对应见src/middlewares/validation-chain-builders.ts#L10-L50链构造函数绑定的请求位置全量选择写法典型场景check()body、cookies、headers、params、query全部check().custom(...)校验整体请求上下文body()req.bodybody()或body()字符串/数组/数字请求体cookie()req.cookiescookie()校验整块 Cookie 对象header()req.headersheader()校验整个头对象param()req.paramsparam()校验整个路径参数对象query()req.queryquery()校验整个查询字符串对象这些构造函数都由buildCheckFunction(locations)生成内部统一委托给check(fields, locations, message)。因此全量选择的底层规则完全一致字段为空 → 选中整个位置。底层原理字段选择与请求位置展开理解全量请求体验证离不开 express-validator 的字段选择模型。一个验证链最终经历如下过程可结合源码验证构造上下文body()创建的链内部持有ContextBuildersetFields([])、setLocations([body])见src/middlewares/check.ts#L17-L20与src/context-builder.ts#L14-L22选择字段实例真正执行时ContextRunner调用selectFields(req, [] , [body])见src/field-selection.ts#L10-L21对所有字段 × 位置做笛卡尔展开再按pathlocation去重空路径特判expandField()中path 时直接取req[location]整体作为value见src/field-selection.ts#L34这就是全量选择的本质执行验证/清洗每个FieldInstance依次经过验证链上的所有校验器如isEmail()与清洗器如trim()、escape()结果写入对应Context。正因为第 3 步的空路径特判全量选择与字段级选择的代码路径是统一且稳定的——这也是为什么body()、body()两种写法长期并存、效果完全一致。全量验证的进阶组合通配符Wildcard与 Globstar全量选择解决的是请求体根就是数据的场景若请求体是一个对象/数组但你希望批量命中其中所有同类字段则属于字段选择的高级特性。以下内容同样来自仓库的docs/guides/field-selection.md与全量选择共同构成选择数据的完整工具箱。通配符*命中数组所有下标或对象所有键*可替换任意一个字段段精确命中该层数组的所有下标、或该层对象的所有键每个命中字段都会作为独立实例分别验证/清洗若所在数组或对象为空则什么都不验证。假设更新用户资料接口接收如下请求体{ addresses: { home: { number: 35 }, work: { number: 501 } }, siblings: [{ name: Maria von Validator }, { name: Checky McCheckFace }] }可用两条链验证所有地址编号为整数、所有兄弟名为非空app.post( /update-user, body(addresses.*.number).isInt(), body(siblings.*.name).notEmpty(), (req, res) { // Handle request }, );源码实现src/field-selection.ts#L98-L102中expandPath遇到*段时对Object.keys(object)逐键递归展开每个键生成一个独立FieldInstance印证了文档每个命中字段被独立验证的表述。Globstar**无限深度命中所有同名嵌套字段当嵌套层级未知时如递归结构的组织架构图用**无限深度命中{ name: Team name, teams: [{ name: Subteam name, teams: [] }] }app.put(/update-chart, body(**.name).notEmpty(), (req, res) { // Handle request });该链会检查req.body根部的name以及任意深度嵌套的name是否非空。其递归实现位于src/field-selection.ts#L103-L117对每个键同时尝试继续用**展开与跳过当前段继续匹配剩余路径两条分支最后按路径去重。实战提示当请求体本身就是普通对象时全量选择 通配符/Globstar是互补的两种策略——前者把根数据视为整体适用于裸字符串/数组/数字后者把根数据视为容器并批量处理内部字段适用于嵌套对象。版本说明与迁移要点本文核心代码取自 v5.2.0 文档website/versioned_docs/version-5.2.0/feature-whole-body-validation.md。若你正在使用较新版本请注意以下差异导入路径v5 文档中的require(express-validator/check)在 v6 中已弃用并会打印警告应改为require(express-validator)见docs/migration-v5-to-v6.md的 Deprecations 小节。body()等链构造函数本身从 v5 到 v7 持续可用只是统一从主入口导入整体行为不变v6.15.0 版本的同名文档website/versioned_docs/version-6.15.0/feature-whole-body-validation.md保留了与 v5.2.0 几乎一致的示例代码与 HTTP 请求仅更新了导入语句证明全量请求体验证这一核心能力跨版本稳定运行环境当前仓库package.json声明engines: { node: 14.0.0 }依赖validator ~13.15.35与lodash使用本文示例前请确保 Node 版本满足要求。延伸阅读字段路径语法完整说明含siblings[0]、websites[www.example.com]等特殊键选择field-selection.md从零搭建 Express 应用并接入验证中间件、处理验证结果getting-started.md验证结果读取与格式化validationResultvalidation-result.md链式验证/清洗 API 全览src/chain/validation-chain.ts、src/chain/validators.ts、src/chain/sanitizers.ts字段选择与未知字段判定的核心实现field-selection.ts链构造函数的默认参数与请求位置绑定实现check.ts、validation-chain-builders.ts赞分享后端【免费下载链接】express-validatorAn express.js middleware for validator.js.项目地址https://gitcode.com/gh_mirrors/ex/express-validator点击查看免费下载相关推荐express-validator 整请求体校验Whole Body Validation直接验证字符串、数组与数字型 req.bodyexpress validator 整请求体校验Whole Body Validation直接验证字符串、数组与数字型 req.body 导读 在绝大多数后端express-validator 全请求体验证Whole Body Validation直接校验字符串、数组与数字类型的请求体express validator 全请求体验证Whole Body Validation直接校验字符串、数组与数字类型的请求体 当请求体不是普通的 JS后端express-validator 全请求体校验直接验证字符串、数组或数字类型的 req.bodyexpress validator 全请求体校验直接验证字符串、数组或数字类型的 req.body 本篇技术指南围绕 express validator v6后端上一篇告别卡顿PySimpleGUI帧动画全攻略从GIF播放到复杂场景控制下一篇Seafile LDAP用户同步属性映射与组权限同步配置创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考