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) {})
转到这些也会访问/:用户名路由。
如何防止这种情况?
(/:用户名路由是代码中的最后一个)
答案 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
})