当多个路径匹配时,Express如何知道要使用哪个路由器路径?

时间:2015-07-26 01:31:17

标签: angularjs node.js mongodb express mean-stack

假设有2个router.route(),例如:

router.route('/app/:id').get(funtion(req, res, next){
    console.log("id route")
});

router.route('/app/:username').get(funtion(req, res, next){
    console.log("user route")
});

调用GET /app/nsuzuki时,使用哪个router.route()?为什么?

1 个答案:

答案 0 :(得分:4)

要完全理解这一点,请阅读文档:http://expressjs.com/api.html#router.METHOD

Express路径如何捕获路径

当您使用:param作为路径的一部分时,它会匹配/*之类的所有内容,并且捕获的值会存储在req.params.param中。

如果您有多个规则,则注册的第一个规则是第一个检查的规则。它会针对每个规则检查每个调用,直到找到匹配项。如果您在没有传递任何值的情况下调用next(),它将查找下一个匹配项(在同一路径中,或继续进入下一个中间件)。

所以这三条规则都将运行

var handleRoute = function(req, res, next){
   console.log(req.path + ' ' + req.params.id + ' ' + req.params.user + ' ' + req.params[0]);
   next();
}

route.route('/user/:id').get(handleRoute);
route.route('/user/:user').get(handleRoute);
route.route('/user/*').get(handleRoute);

当我请求/user/foobar时,我会看到以下输出(可能是客户端的错误,因为我从未回复过:P)

/user/foobar foobar undefined undefined
/user/foobar undefined foobar undefined
/user/foobar undefined undefined foobar

它会击中所有三个,但每个上下文都不同。

如何使用正则表达式捕获路径模式

如果你想捕获id(让我们说所有数字)和用户名(所有字母)的单独路线,你可以这样做:

var handleRoute = function(tag) {
  return function(req, res, next) {
    console.log(tag + ' ' + req.path + ' -> ' + req.params[0]);
    res.status(200)
      .json({
        success: 'yay!'
      });
  };
};

route.route(/^\/user\/([0-9]+)$/i)
  .get(handleRoute('id'));
route.route(/^\user\/([A-Za-z]+)$/i)
  .get(handleRoute('user'));
route.route('/user/*')
  .get(handleRoute('catch all'));

请注意我的捕获组周围的模式。如果没有这个,params为空。它在字符串中只用*自动捕获,因为它们是很好的人。当我针对三种不同的类型运行时,我会得到以下输出。

id /user/123 -> 123
user /user/user -> user
catch all /user/user.1 -> user.1

所有这些都解释了,你正在向自己打开一些错误来感染你的系统。可能想要考虑一下你的网址格式。