完全指南:ValidationChain 内置净化方法详解)
后端【免费下载链接】express-validatorAn express.js middleware for validator.js.项目地址https://gitcode.com/gh_mirrors/ex/express-validator点击查看免费下载本文聚焦 express-validator 7.x 中ValidationChain提供的全部标准净化器Standard Sanitizers从字符串清理trim、blacklist、whitelist到类型转换toBoolean、toDate、toFloat、toInt再到 HTML 安全escape/unescape与邮箱规范化normalizeEmail。读完本文你将掌握每个净化器的函数签名、参数含义与默认行为理解净化值如何被写回请求对象并能直接用这些方法构建安全、健壮的 Express 中间件链。什么是标准净化器在 express-validator 中ValidationChain验证链拥有三类方法校验器validators、净化器sanitizers和修饰器modifiers。净化器的职责是变换字段的值——去除噪音、把值转换为正确的 JavaScript 类型或提供基础的安全防线。与校验器不同净化器不会产生校验错误而是把处理后的新值持久化写回请求对象让后续的 express-validator 函数、你的路由处理器乃至其他中间件都能使用净化后的结果参见 docs/guides/validation-chain.md 中 Sanitizers persist the updated field value back into the request 的说明。所谓标准净化器指的是 express-validator 从 validator.js 中的Sanitization类实现。本文所讲解的 14 个标准净化器均以ValidationChain上方法的形式暴露完整清单定义于 src/chain/sanitizers.ts 的SanitizersReturn接口中而具体实现则在 src/chain/sanitizers-impl.ts。字符串清理类净化器这一类净化器负责去除字符串中的无用字符是最常用的净化手段常与校验器组合使用典型场景如先trim再isEmail。blacklist(chars: string)blacklist(chars: string): ValidationChain删除字符串中所有出现在chars字符列表里的字符注意是逐个字符匹配而非子串匹配。实现上直接委托给validator.blacklistsrc/chain/sanitizers-impl.ts// 移除字符串中的所有 a、b 和 c body(code).blacklist(abc); // 入参 abc123xyz - 净化后 123xyzwhitelist(chars: string)whitelist(chars: string): ValidationChain与blacklist相反只保留chars中列出的字符其余全部删除。实现同样委托给validator.whitelistsrc/chain/sanitizers-impl.ts// 只保留数字字符 body(phone).whitelist(0123456789); // 入参 (123) 456-7890 - 净化后 1234567890ltrim(chars?: string)/rtrim(chars?: string)/trim(chars?: string)ltrim(chars?: string): ValidationChain rtrim(chars?: string): ValidationChain trim(chars?: string): ValidationChaintrim()去除字符串两端的空白字符默认去除空格、制表符、换行等空白可选传入chars指定要去除的字符集合。ltrim()只去除左端开头的空白或指定字符。rtrim()只去除右端结尾的空白或指定字符。三者分别映射到validator.trim/validator.ltrim/validator.rtrimsrc/chain/sanitizers-impl.tsbody(username).trim(); // john - john body(title).ltrim(-#); // ##Hello - Hello body(trailing).rtrim(!?); // Hello!? - Hello组合顺序的重要性净化器的执行顺序遵循调用顺序这点在实际使用中极易踩坑。参考 docs/guides/validation-chain.md 的示例// 先校验非空、再 trim —— 可能产生误判 query(search_query).notEmpty().trim();如果用户传入的search_query全是空白字符notEmpty()会通过随后trim()把值清空最终得到假阳性。正确的做法是先净化、后校验query(search_query).trim().notEmpty();在单元测试 src/chain/sanitizers-impl.spec.ts 中可以确认ltrim(a)、rtrim(z)、trim(az)等调用都会向上下文添加对应的Sanitization项。stripLow(keep_new_lines?: boolean)stripLow(keep_new_lines?: boolean): ValidationChain移除字符串中所有 ASCII 控制字符0-31 和 127 号字符用于清理用户输入中的隐形控制字符。可选参数keep_new_lines默认为false设为true时保留换行符\n适用于需要在净化后保留多行文本格式的场景body(message).stripLow(true); // 删除控制字符但保留换行 body(single_line).stripLow(); // 连换行一并删除escape()/unescape()escape(): ValidationChain unescape(): ValidationChainescape()把字符串中的 HTML 特殊字符、、、、替换为对应的 HTML 实体lt;、gt;、amp;、quot;、#x27;是抵御 XSS跨站脚本攻击的基础手段。unescape()escape()的逆操作把 HTML 实体还原为普通字符。实战用escape()防御 XSSdocs/guides/getting-started.md 中给出了最典型的应用当用户可以在查询参数中注入script标签时使用escape()将其转义为文本。改造后的路由如下const express require(express); const { query, validationResult } require(express-validator); const app express(); app.use(express.json()); app.get(/hello, query(person).notEmpty().escape(), (req, res) { const result validationResult(req); if (result.isEmpty()) { return res.send(Hello, ${req.query.person}!); } res.send({ errors: result.array() }); }); app.listen(3000);访问/hello?personbJohn/b时页面输出 Hello, bJohn/b!原始 HTML 被转义为文本XSS 注入不再生效。escape()与unescape()在 src/chain/sanitizers-impl.spec.ts 中被验证为以空参数数组[]添加标准净化项。邮箱规范化normalizeEmail(options?)normalizeEmail(options?: { all_lowercase?: boolean; gmail_lowercase?: boolean; gmail_remove_dots?: boolean; gmail_remove_subaddress?: boolean; gmail_convert_googlemaildotcom?: boolean; outlookdotcom_lowercase?: boolean; outlookdotcom_remove_subaddress?: boolean; yahoo_lowercase?: boolean; yahoo_remove_subaddress?: boolean; icloud_lowercase?: boolean; icloud_remove_subaddress?: boolean; }): ValidationChainnormalizeEmail()会把邮箱地址规范化为标准形式例如把 FooBar.com 规范化为foobar.com。它支持 11 个可选的布尔选项针对不同邮件服务商的规范化规则各选项作用如下选项作用all_lowercase邮箱整体转为小写gmail_lowercaseGmail 地址转为小写默认开启gmail_remove_dots移除 Gmail 用户名中的点号如john.doe→johndoe默认开启gmail_remove_subaddress移除 Gmail 的 子地址如johntaggmail.com→johngmail.com默认开启gmail_convert_googlemaildotcom把googlemail.com转换为gmail.com默认开启outlookdotcom_lowercaseOutlook.com 地址转为小写outlookdotcom_remove_subaddress移除 Outlook.com 的 子地址yahoo_lowercaseYahoo 地址转为小写yahoo_remove_subaddress移除 Yahoo 的 - 子地址icloud_lowercaseiCloud 地址转为小写icloud_remove_subaddress移除 iCloud 的 子地址需要说明的是各服务商的选项默认启用情况以 validator.js 的具体实现为准。用法示例body(email).normalizeEmail(); // 显式关闭 Gmail 点号去除保留 john.doe 原样 body(email).normalizeEmail({ gmail_remove_dots: false }); // 完全按默认规则规范化后再校验 body(email).normalizeEmail().isEmail();在 src/chain/sanitizers-impl.spec.ts 中可以看到不传参数调用normalizeEmail()时options 以undefined传入Sanitization最终由validator.normalizeEmail使用其内置默认值。值得注意的是当前仓库最新文档 docs/api/validator/_sanitizers.md 中该签名还额外包含yandex_convert_yandexru?: boolean选项用于将yandex.ru转换为yandex.com而本指南所对应的 7.0.0 版本文档未包含此项——如果你使用的是更新版本可查阅上述最新文档确认完整选项集。类型转换类净化器这一类净化器把字符串转换为对应的 JavaScript 类型对于需要从req.body直接拿到数字、日期或布尔值的业务场景非常实用。toBoolean(strict?: boolean)toBoolean(strict?: boolean): ValidationChain把字符串转换为布尔值。默认宽松模式下1、true、yes、on等会被转换为true0、false、no、off等转换为false同时保留字符串的大小写不敏感匹配。若传入strict: true则只接受true和false且大小写敏感body(newsletter_opt_in).toBoolean(); // true - true, 1 - true, false - false body(agreed).toBoolean(true); // 仅 true/false 会被识别其余保持原值toDate()toDate(): ValidationChain把日期格式的字符串转换为 JavaScriptDate对象。解析失败时返回NaN实际上仍会被写回需配合校验或在使用处判断body(birthday).toDate(); // 2016-01-17 - Date 对象toFloat()toFloat(): ValidationChain把字符串转换为浮点数使用parseFloat的解析规则body(price).toFloat(); // 3.14 - 3.14toInt(radix?: number)toInt(radix?: number): ValidationChain把字符串转换为整数。可选参数radix指定进制2-36默认为 10十进制body(age).toInt(); // 42 - 42 body(hex).toInt(16); // ff - 255toBoolean、toDate、toFloat、toInt的底层分别委托给validator.toBoolean/validator.toDate/validator.toFloat/validator.toIntsrc/chain/sanitizers-impl.ts数组元素的逐项转换同样由Sanitization类负责。净化器的底层执行原理理解净化值如何回到请求对象有助于排查链式调用中的顺序问题。标准净化器 vs 自定义净化器从 src/chain/sanitizers.ts 可以看出Sanitizers接口包含两类净化方法自定义净化器customSanitizer、default、replace、toArray、toLowerCase、toUpperCase——由 express-validator 自己实现标准净化器本文讲解的 14 个方法——直接包装 validator.js 的净化函数。两者的关键差异在 src/chain/sanitizers-impl.ts 中体现标准净化器通过addStandardSanitization()以custom: false注册Sanitization而自定义净化器以custom: true注册。执行流程Sanitization.run()核心执行逻辑位于 src/context-items/sanitization.ts自定义净化器直接以(value, meta)调用函数可返回 Promise支持异步净化然后把返回值写回上下文标准净化器先把字段值数组则逐元素转换为字符串再以(stringifiedValue, ...options)调用对应的 validator.js 函数最后通过context.setData(path, newValue, location)把净化后的值写回请求的对应位置如req.body、req.query、req.params这正是净化结果能在路由处理器中被读取的原因。单元测试 src/context-items/sanitization.spec.ts 验证了标准净化器会逐个处理数组元素如[1, 42]→ 对每个元素分别调用、会把附加 options 传给净化函数如[bar, false]、并持久化净化值回上下文src/chain/sanitizers-impl.spec.ts 则验证了每个标准净化器方法都正确地以new Sanitization(validatorFn, false, options)注册。与校验链的组合模式净化器几乎总是与校验器、修饰器配合使用形成净化 → 校验 → 条件控制的完整链式结构。完整的链式方法参考 docs/api/validation-chain.md常用组合示例const { body } require(express-validator); app.post( /signup, body(email) .trim() // 先净化去空白 .normalizeEmail() // 再净化规范化邮箱 .isEmail() // 后校验必须是合法邮箱 .withMessage(Invalid email), body(age) .toInt() // 转换为数字 .isInt({ min: 18, max: 120 }), // 再校验年龄范围 body(bio) .optional() .stripLow() // 清除控制字符 .escape(), // 转义 HTML防 XSS (req, res) { // req.body.email、req.body.age 已是净化后的值 res.json({ ok: true }); }, );注意toBoolean、toDate、toFloat、toInt这类转换净化器改变了值的类型因此放在它们之后的校验器如isInt可能不再按字符串规则工作链式编排时应把类型转换放在校验之前、把纯字符串净化trim、blacklist等放在校验之前或之间依据实际需求决定顺序。小结express-validator 的标准净化器把 validator.js 的字符串净化能力无缝接入了 Express 中间件体系覆盖了日常开发中最常见的三类需求清理字符串trim/ltrim/rtrim空白与指定字符、blacklist/whitelist字符白名单/黑名单、stripLowASCII 控制字符保障安全escape/unescapeHTML 实体转义防 XSS、normalizeEmail邮箱规范化含 Gmail/Outlook/Yahoo/iCloud 等专项规则转换类型toBoolean支持严格模式、toDate、toFloat、toInt支持自定义进制。每个方法返回ValidationChain自身因此可以与其他校验器、修饰器无限链式组合。所有标准净化器在底层都会先把值字符串化数组逐元素处理再调用 validator.js 函数最后把结果写回请求对象——理解这一机制就能在编排净化顺序时避免先校验后净化导致的假阳性写出既安全又符合直觉的校验中间件。如需查看全部净化器的接口声明可阅读 src/chain/sanitizers.ts 与 src/chain/sanitizers-impl.ts完整的验证链 API含自定义净化器customSanitizer、default、replace、toArray、toLowerCase、toUpperCase等参见 docs/api/validation-chain.md。赞分享后端【免费下载链接】express-validatorAn express.js middleware for validator.js.项目地址https://gitcode.com/gh_mirrors/ex/express-validator点击查看免费下载相关推荐express-validator ValidationChain 完全指南内置校验器、净化器与修饰器精讲express validator ValidationChain 完全指南内置校验器、净化器与修饰器精讲 ValidationChain 是 express后端express-validator 7.2 sanitizer API 完全指南内置净化器与 ValidationChain 数据清洗实战express validator 7.2 sanitizer API 完全指南内置净化器与 ValidationChain 数据清洗实战 导读 本文以 ex后端express-validator 校验链ValidationChain权威指南内置校验器、净化器与修饰符全解析express validator 校验链ValidationChain权威指南内置校验器、净化器与修饰符全解析 ValidationChain 是 ex后端上一篇AzurLaneAutoScript技术架构解析基于图像识别的碧蓝航线全自动化实现下一篇如何为DDE on openEuler开发扩展插件开发者终极入门指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考