Express 快速路由:使用router.use/all和router.param控制流
我想使用这种中间件验证params。问题是router.param总是在第一个中间件router.all之前应用(我也尝试了router.use,它不起作用,因为两个中间件都使用param)。有没有办法在router.param之前执行中间件1Express 快速路由:使用router.use/all和router.param控制流,express,express-router,Express,Express Router,我想使用这种中间件验证params。问题是router.param总是在第一个中间件router.all之前应用(我也尝试了router.use,它不起作用,因为两个中间件都使用param)。有没有办法在router.param之前执行中间件1 // Middleware 1 router.all('/:firstId/checklist/:**secondId**/*', (req, res, next) => { console.log('Request matched'
// 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,记录“请求匹配”
,则根据请求相应地应用下一个中间件。如果它不是一个有效的id,“请求匹配”
未被记录,则预期的错误是响应中发送的未被记录。我从来自router.param的Mongoose中得到此错误:
MongooseError [CastError]: Cast to ObjectId failed for value "xxx" at path "_id" for model "XXX"
我试图对router.param进行注释,它解决了问题。因此,它肯定与执行顺序有关
非常感谢您的帮助翻转这一点(原因是在您的案例中,express在这两种情况下都只查找: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
)
到
我找不到一种方法来使用与router.param参数相同的中间件,并在router.param之前执行它,因为router.param似乎是首先系统地执行的。但有一种解决方法可以做到这一点:在单独的文件中重新组合要在router.param之前执行的中间件 而不是: app.js(主应用程序文件)路由到原始路由器(原始路由器文件) 控制流程应为: app.js(主应用程序文件)路由到
beforeParamMiddlewwareRouter
路由到原始路由器
(原始路由器文件)
或
在app.js中:
app.use('/path', beforeParamMiddlewwareRouter, originalRouter)
如果您有更好的解决方案,请随时提供。我愿意接受建议。翻转不起作用。checkValidationErrors使用next(),因此如果secondId有效,则会调用这两个中间件(我使用了几个console.log()来确保),如果secondId无效,则只调用第一个中间件。我更新了问题,因为问题似乎更多地与有问题的中间件和使用router.param的另一个中间件之间的执行顺序有关。
app.use('/path', beforeParamMiddlewwareRouter, originalRouter)