当前位置: 首页 > news >正文

Node| 如何创建一个自定义的验证中间件?

目录

1. 基础结构:自定义中间件原理

2. 实战示例:手动编写验证中间件

步骤一:定义验证中间件

步骤二:在路由中使用

3. 进阶方式:使用 express-validator 库

4. 高级技巧:可复用的验证工厂

✔ 最佳实践总结 ✔


在 Express.js 中创建自定义验证中间件,核心在于编写一个能够访问req(请求对象)、res(响应对象)和next(下一个中间件函数)的函数。该函数负责检查请求数据,若验证失败则直接终止请求并返回错误,若验证通过则调用next()将控制权交给后续处理逻辑。

以下是创建和使用自定义验证中间件的完整指南:

1. 基础结构:自定义中间件原理

Express 中间件是一个标准的 JavaScript 函数,其签名如下:

function middlewareName(req, res, next) { // 1. 执行验证逻辑 // 2. 如果验证失败:res.status(400).json({ error: '...' }) // 3. 如果验证成功:next() }

关键点:

  • 必须调用next()‌:如果验证通过,必须调用next(),否则请求会挂起,客户端收不到响应。
  • 提前终止‌:如果验证失败,发送响应后‌不要‌调用next(),以防止执行后续的业务逻辑。

2. 实战示例:手动编写验证中间件

假设我们需要验证用户注册接口,确保usernameemail字段存在且格式正确。

步骤一:定义验证中间件

你可以创建一个独立的函数或模块来封装验证逻辑。

// middleware/validateUser.js const validateUser = (req, res, next) => { const { username, email } = req.body; const errors = []; // 验证用户名 if (!username || typeof username !== 'string' || username.trim().length < 3) { errors.push('Username is required and must be at least 3 characters long'); } // 验证邮箱格式 const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!email || !emailRegex.test(email)) { errors.push('Valid email address is required'); } // 如果有错误,返回 400 状态码并停止后续执行 if (errors.length > 0) { return res.status(400).json({ status: 'error', message: 'Validation failed', details: errors }); } // 验证通过,继续执行下一个中间件或路由处理器 next(); }; module.exports = validateUser;
步骤二:在路由中使用

将中间件挂载到特定的路由上。注意中间件函数的顺序:验证中间件必须在业务逻辑处理函数之前。

const express = require('express'); const app = express(); const validateUser = require('./middleware/validateUser'); // 解析 JSON 请求体 app.use(express.json()); // POST /register 路由 // 顺序:1. parse JSON -> 2. validateUser -> 3. handler app.post('/register', validateUser, (req, res) => { // 此时可以确信 req.body.username 和 req.body.email 是有效的 const { username, email } = req.body; // 模拟数据库操作 console.log(`Creating user: ${username}, ${email}`); res.status(201).json({ status: 'success', message: 'User registered successfully', data: { username, email } }); }); app.listen(3000, () => console.log('Server running on port 3000'));

3. 进阶方式:使用express-validator

对于复杂项目,手动编写正则表达式和条件判断容易出错且难以维护。推荐使用业界标准的express-validator库,它基于validator.js,提供了链式调用的验证规则和数据净化功能。

安装:

npm install express-validator

实现代码:

const { body, validationResult } = require('express-validator'); const express = require('express'); const app = express(); app.use(express.json()); // 定义验证规则数组 const registerValidationRules = [ body('username') .trim() .notEmpty().withMessage('Username is required') .isLength({ min: 3 }).withMessage('Username must be at least 3 characters'), body('email') .normalizeEmail() .isEmail().withMessage('Invalid email format'), body('password') .isLength({ min: 8 }).withMessage('Password must be at least 8 characters') .matches(/[0-9]/).withMessage('Password must contain a number') ]; // 通用错误处理中间件(可选,用于统一处理验证结果) const handleValidationErrors = (req, res, next) => { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } next(); }; // 应用验证规则 app.post('/register', registerValidationRules, // 1. 执行验证规则 handleValidationErrors, // 2. 检查验证结果 (req, res) => { // 3. 业务逻辑 res.json({ message: 'User created', data: req.body }); } ); app.listen(3000);

4. 高级技巧:可复用的验证工厂

为了进一步提高代码复用性,可以创建一个“工厂函数”来生成针对特定字段的验证中间件。

const { body, validationResult } = require('express-validator'); // 创建一个通用的验证中间件生成器 const createValidator = (validations) => { return async (req, res, next) => { // 执行所有传入的验证规则 await Promise.all(validations.map(validation => validation.run(req))); const errors = validationResult(req); if (errors.isEmpty()) { return next(); } res.status(400).json({ errors: errors.array() }); }; }; // 定义具体的验证规则 const userRegistrationValidations = [ body('email').isEmail(), body('password').isLength({ min: 6 }) ]; // 生成中间件 const validateRegistration = createValidator(userRegistrationValidations); // 使用 app.post('/signup', validateRegistration, (req, res) => { res.send('Signup successful'); });

✔ 最佳实践总结 ✔

  1. 分离关注点‌:验证中间件只负责数据格式和完整性检查,不应包含数据库查询或业务逻辑(如“用户是否已存在”属于业务逻辑,但“邮箱格式是否正确”属于验证)。
  2. 统一错误格式‌:确保所有验证失败的响应具有相同的 JSON 结构,便于前端统一处理。
  3. 数据净化‌:在验证的同时进行数据清洗(如trim()去除空格,escape()防止 XSS),express-validator内置了这些功能。
  4. 异步支持‌:如果验证需要查询数据库(如检查用户名唯一性),中间件函数应声明为async,并使用await等待异步操作完成。
  5. 位置安排‌:确保验证中间件位于express.json()之后,以便能访问到解析后的req.body

通过上述方法,你可以构建出既安全又易于维护的请求验证层,有效保护你的 Express 应用免受无效或恶意数据的侵害。


☑ 相关参考 ☑

Node | 如何在Express.js中处理异步验证逻辑

Nodejs | 深入理解Express框架之如何使用各类中间件

http://www.cnnetsun.cn/news/3035446.html

相关文章:

  • 第53篇:验证码识别 - CNN与深度学习实战
  • 第55篇:代理池架构与IP管理策略
  • 第60篇:爬虫安全与合规实战
  • 影刀RPA新手教程:OCR文字识别完全指南——让影刀读懂图片里的文字
  • 海王IM即时通讯----沟通工具的增多,并未带来协作效率的同步提升
  • Spring AI 集成 DeepSeek 原生供应商:告别 OpenAI 兼容层,获取结构化推理过程
  • OSINT Cheat Sheet:一份覆盖全场景的开源情报工具速查表
  • RSS 生态全收录:一份持续更新的资源清单
  • Query Loop 如何驱动任务闭环
  • YOLO检测头改进- 第38篇:Anchor-Free与Anchor-Based检测头融合方案
  • UnityUI中使用中文文本
  • 2026上海小程序开发公司排行:哪家好?商城、会员与预约项目怎么选
  • 【JAVA毕设源码分享】基于SpringBoot的智慧医疗问诊系统的设计与实现(程序+文档+代码讲解+一条龙定制)
  • 紫外线变色硅胶垫片,为您的防晒衣加上一双“慧眼”
  • 除了大厂算法岗,AI大模型应用开发还能做什么?这5个方向缺口
  • 【Springboot毕设全套源码+文档】基于SpringBoot的停车管理系统的设计与实现(丰富项目+远程调试+讲解+定制)
  • 终于找到免费开源TTS模型,克隆声音不要钱,本地电脑也能跑
  • 【信道估计】太赫兹集成UM-MIMO和IRS系统的混合球面与平面波信道建模与估计【含Matlab源码 15665期】
  • 手把手教你用8款AI论文写作软件,极速搞定各类论文
  • 专业级AI无人直播系统
  • K-431S高性能增韧型瞬干胶技术参数与选型参考
  • playwright-setInputFiles 上传文件
  • 2026年GEO优化系统源码如何选?三大核心指标帮你避坑
  • 道歉声明登报如何写?道歉声明登报咋办理?多少钱?
  • 【朱红大漆戗金梅花碗】一剪红梅献祖国
  • 选题指导,LW(文理科均可)
  • 2026年泉州GEO优化优质服务商最新推荐
  • 重塑创业思维、培养创新能力必看书籍推荐
  • 帝国理工学院研究团队破解“电力调度难题“
  • 斯坦福、伯克利等:如何从零开始“喂饱“一个能干活的AI智能体?