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. 实战示例手动编写验证中间件假设我们需要验证用户注册接口确保username和email字段存在且格式正确。步骤一定义验证中间件你可以创建一个独立的函数或模块来封装验证逻辑。// 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); });✔ 最佳实践总结 ✔‌分离关注点‌验证中间件只负责数据格式和完整性检查不应包含数据库查询或业务逻辑如“用户是否已存在”属于业务逻辑但“邮箱格式是否正确”属于验证。‌统一错误格式‌确保所有验证失败的响应具有相同的 JSON 结构便于前端统一处理。‌数据净化‌在验证的同时进行数据清洗如trim()去除空格escape()防止 XSSexpress-validator内置了这些功能。‌异步支持‌如果验证需要查询数据库如检查用户名唯一性中间件函数应声明为async并使用await等待异步操作完成。‌位置安排‌确保验证中间件位于express.json()之后以便能访问到解析后的req.body。通过上述方法你可以构建出既安全又易于维护的请求验证层有效保护你的 Express 应用免受无效或恶意数据的侵害。☑ 相关参考 ☑Node | 如何在Express.js中处理异步验证逻辑Nodejs | 深入理解Express框架之如何使用各类中间件