我想使用这类中间件来验证参数。问题是router.param总是在第一个中间件router.all之前应用(我也尝试过router.use,它不起作用,因为param对两个中间件都通用)。是否可以在router.param之前执行中间件1?
// Middleware 1
router.all('/:firstId/checklist/:**secondId**/*',
(req, res, next) => {
console.log('Request matched')
next()
},
param('**secondId**', "Error message 2")
.isMongoId(),
checkValidationErrors
)
router.param('**secondId**', callback)
但是,中间件1不能按我预期的那样工作。如果参数是有效的MongoDB ObjectId,则记录'Request matched'
,根据请求相应地应用下一个中间件。如果它不是有效的ID,则记录'Request matched'
NOT ,则响应中发送的预期错误为 NOT 。我从router.param的Mongoose那里得到了这个错误:
MongooseError [CastError]: Cast to ObjectId failed for value "xxx" at path "_id" for model "XXX"
我试图评论router.param,它解决了问题。因此,它当然与执行顺序有关。
非常感谢您的帮助
答案 0 :(得分:0)
将其翻转(在您的情况下,原因是在两种情况下都只查找:firstId/*
,因为它同时适合两种情况。如果第一个模式/路径与输入URI匹配,则不会查找)用于您的中间件2。
// Middleware 1
router.all('/:firstId/*',
param('firstId', "Error message 1")
.isMongoId(),
checkValidationErrors
)
// Middleware 2
router.all('/:firstId/checklist/:secondId/*',
(req, res, next) => {
console.log('Request matched')
next()
},
param('secondId', "Error message 2")
.isMongoId(),
checkValidationErrors
)
收件人
// Middleware 2
router.all('/:firstId/checklist/:secondId/*',
(req, res, next) => {
console.log('Request matched')
next()
},
param('secondId', "Error message 2")
.isMongoId(),
checkValidationErrors
)
// Middleware 1
router.all('/:firstId/*',
param('firstId', "Error message 1")
.isMongoId(),
checkValidationErrors
)
答案 1 :(得分:0)
我找不到一种使用与router.param相同参数的中间件并在router.param之前执行的方法,因为router.param似乎是首先被系统地执行。但是,有一种解决方法可以做到这一点:将要执行的中间件重新分组到router.param之前的单独文件中。
代替:
app.js(主应用程序文件)路由到originalRouter
(原始路由器文件)。
控制流程应为:
app.js(主应用程序文件)路由到beforeParamMiddlewwareRouter
,路由到originalRouter
(原始路由器文件)
OR
在app.js中:
app.use('/path', beforeParamMiddlewwareRouter, originalRouter)
如果有的话,随时提供更好的解决方案。我愿意接受建议。