Node.js使用Joi做参数校验未触发预期报错的问题排查
问题定位
核心错误出在validateRequest.js中间件的返回值解构逻辑:Joi 官方标准包的validate()方法执行后,返回的对象中校验错误对应的属性名是**error**,你代码里写的是解构err,导致实际拿到的err永远是undefined,错误判断分支永远不会触发,无论请求体是否符合校验规则,都会直接走next()放行到后续业务处理逻辑,自然不会抛出校验错误。
额外提示:你代码里打印validateDataRepo['$_root']属于调试残留,上线前可以删掉,不影响功能但无保留必要。另外要确认Express入口文件已经配置了app.use(express.json()),否则POST请求的JSON请求体不会被正确解析到req.body上。
修复方案
只需要修改中间件里解构返回值、判断错误的两行代码即可,修复后的完整中间件代码如下:
const Joi = require('joi'); module.exports.validateRequest = (schema) => { return (req, res, next) => { const options = { abortEarly: false, // 收集所有校验错误,不遇到第一个错误就终止 allowUnknown: true, // 允许请求体携带schema未定义的字段 stripUnknown: true // 校验通过后,自动剥离请求体里未在schema中定义的字段 }; // 修正:解构error字段,而非err const { error, value } = schema.validate(req.body, options); if (error) { next(`Validation error: ${error.details.map(x => x.message).join(', ')}`); } else { req.body = value; next(); } }; };
验证效果
修复后重新发起带请求体{ "ownerId": "t" }的POST请求,会正常抛出校验错误,包含两个不符合规则的提示:
ownerId长度小于要求的最小长度5- 必填字段
uri缺失
另外你的Schema定义写法没有问题,Joi.object().keys({...})和简写的Joi.object({...})效果完全一致,不需要额外修改。
内容的提问来源于stack exchange,提问作者Sam T
相关产品推荐
相关产品推荐

