expressjs / nodejs与通配符冲突的一般路由

时间:2017-05-12 15:56:20

标签: node.js express

full code looks like this

		/* /login [get] */
		app.get('/login', function(req, res) {
		  res.render('login');
          return;
		});


	app.get('/stats', requireLogin, function(req, res) {
		User.findOne({ _id: req.user.id})
		.populate('current')
		.exec(function(err, stats) {
			if (err) res.json(err)
			res.render('stats', stats);
			return;
		})
	});
		/* /username */
		app.get('/:username', requireLogin, function(req, res) {
			console.log("sdf");
			User
			.findOne({ username: req.params.username }, 'friends')
			.exec(function(err, user) {
				console.log(user)
			})
      
going to /login  renders the login page, but also triggers the console.log of "sdf from the next route

在我的应用中,可以访问/ someusername

我将该路线定义为

app.get('/:username', function(req, res) {

但是因为我也有像/ stats和/ login

这些一般的
app.get('/stats', function(req, res) {})
app.get('login',  function(req, res) {})

转到这些也会访问/:用户名路由。

如何防止这种情况?

(/:用户名路由是代码中的最后一个)

2 个答案:

答案 0 :(得分:2)

路由按顺序由Express处理。因此,如果您将/stats路由放在/:username路由之前,并且您没有通过调用next()手动强制路由继续继续,那么事情将对您有用。将首先找到并处理更具体的路线。

但是,当您有相互冲突的网址时,这可能是一个糟糕的网址设计。如果用户被命名为"stats“,那么他们的用户名网址将无法运行。如果您想要其他网址,例如/login/about,该怎么办。所有这些都会发生冲突潜在的用户名。这只是一个糟糕的设计。

可能你应该改成这样的东西:

app.get('/user/:username', function(req, res) {...}

因此,任何用户名路由都不会与您的/stats路由或您选择的任何其他顶级路由冲突。这将使您的顶级路径可用于将路线引导到类别中,并且将是更好的URL设计。

而且,正如我们在进一步讨论中发现的那样,请求页面的网站图标的浏览器也会点击您的/:username路由。您可以为favicon创建特殊路径,也可以在页面中插入元标记以阻止favicon请求,也可以停止使用捕获这些类型的顶级通配符路径。请注意,您也可能会遇到诸如机器人请求/robots.txt之类的事情。

答案 1 :(得分:1)

  

(/:用户名路由是代码中的最后一个)

如果您已将用户名路由放在所有其他路由的最后,那么它应该有用。

如果您希望用户名路由位于顶部,则可以在/:用户名路由中进行验证,但不推荐使用,设计不良

var reseredKeywords = ['stats', 'login'];
app.get('/:username', function(req, res, next) {
  if (reseredKeywords.indexOf(req.param.username.toLowerCase())) {
    next();
  }
  // else handle your username here
})