使用 Express.js 的路由器级中间件顺序

Router-level middleware order using Express.js

我有以下路由器:

/* GET /users/username */
router.get("/:username", function(req, res, next) {
  User.findOne({
    username: req.params.username
  }).exec(function(err, user) {
    if (err) return next(error);
    res.json(user);
  });
});

/* GET /users/id */
router.get("/:id", function(req, res, next) {
  User.findById(req.params.id, function(err, user) {
    if (err) return next(err);
    res.json(user);
  });
});

在上面的顺序中,/* GET /users/id */ 将 return 为空,如果我交换顺序 /* GET /users/username */ 将导致此错误:

Cast to ObjectId failed for value "Guest" at path "_id" for model "User"

基本上,第二个中间件被忽略了。但是,不同的行为需要两者。我正在使用 AngularJS $resource 与 RESTful 服务器端数据源进行交互。

  1. 为什么我不能同时使用两者?为什么第二个中间件被忽略了?
  2. 这两个路由器应该以什么顺序工作?

最好通过以下方式进行路由: router.route('your/route').get(aJsFile.function);

然后,不用exec,只写 属性:['id', 'username'] 其中:{用户名:用户名} 或者像这样的东西。

第二个中间件被忽略,因为 url 模式是相同的...你希望路由器如何区分 'username' 或 'id';

你必须首先检查它是否是一个 id。

router.get("/:username", function(req, res, next) {
  const username = req.params.username;
  if (!isNaN(parseInt(username)) {     // <------ Check if it's an ID
     next();
  } else {
  User.findOne({
    username: req.params.username
  }).exec(function(err, user) {
    if (err) return next(error);
    res.json(user);
  });
   }
});

/* GET /users/id */
router.get("/:id", function(req, res, next) {
  User.findById(req.params.id, function(err, user) {
    if (err) return next(err);
    res.json(user);
  });
});