-1

我想使用这些中间件来验证参数。问题是 router.param 总是在第一个中间件 router.all 之前应用(我也尝试了 router.use,它不起作用,因为 param 对两个中间件都是通用的)。有没有办法在 router.param 之前执行 Middleware 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'记录,则不会在响应中发送预期的错误。我从来自 router.param 的 Mongoose 得到这个错误:

MongooseError [CastError]: Cast to ObjectId failed for value "xxx" at path "_id" for model "XXX"                 

我试图评论 router.param 并解决了问题。所以肯定跟执行顺序有关。

非常感谢您的帮助

4

2 回答 2

0

我找不到一种方法来使用与 router.param 具有相同参数的中间件并在 router.param 之前执行它,因为 router.param 似乎首先系统地执行。但是有一种解决方法可以做到这一点:将要在 router.param 之前执行的中间件重新组合到一个单独的文件中。

而不是:app.js(主应用程序文件)路由到originalRouter(原始路由器文件)。

控制流程应该是:app.js(主应用程序文件)路由到beforeParamMiddlewwareRouter路由到originalRouter(原始路由器文件)

或者

在 app.js 中:

app.use('/path', beforeParamMiddlewwareRouter, originalRouter)

如果您有更好的解决方案,请随时提供。我愿意接受建议。

于 2020-01-23T15:26:48.320 回答
0

翻转这个(原因是你的情况 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
)

// 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        
)
于 2020-01-22T20:45:33.173 回答