路由问题,而不是收集req.params

我正在制作一个项目的维基百科克隆。 我最初的编辑路线如下所示:

router.get('/edit/:id', function(req, res){ var id = req.params.id; console.log(id); models.Page.findById(id, function(err, doc){ console.log(doc); res.render('edit', {page: doc}); }); }); 

我正在做的是创build一个页面的编辑页面视图与ID参数的id匹配。 这工作,直到…

我不得不添加这个新的路线:

 router.get('/:url_name/:id', function(req,res){ var id = req.params.id; models.Page.findById(id, function(err, doc){ res.render('show_page', {page: doc}); }); }); 

现在,当我有这条路线激活,我的编辑/:ID页面路线不会收集id参数(req.params.id)。

我迷失在为什么这不工作,我应该开始尝试debugging,因为我没有得到任何错误,它仍然会带我到我的编辑/:身份证页面,但是当我console.log(ID)我做没有收到价值,甚至没有定义,什么都没有。 此外,我传递给我的编辑视图的{page:doc}没有find。

如果任何人都可以提供洞察力或地方开始寻找debugging,我会很感激。 提醒一下,当我没有:url_name /:id路由激活的时候,edit /:id路由就像它应该(req.params.id抓取id)一样工作。

当前路线 –

我加了var wiki_routes = require('./routes/wiki'); 在我的app.js和在这条路线我有:

 // **** URL ROUTES **** router.get('/', function(req, res) { models.Page.find(function(err, docs) { res.render('index', { docs: docs }); }); }); router.get('/:url_name', function(req, res){ var url_name = req.params.url_name; var isUpdated = req.query.updated; var updated = (isUpdated === 'true')?true:false; models.Page.find({url_name: url_name}, function(err, page){ if(page.length > 1){ console.log(page); res.render('disambiguation', {pages: page, updated: updated }); } else { console.log(page); res.render('show_page', {page: page[0], updated: updated}); } }); }); router.get('/:url_name/:id', function(req,res){ var id = req.params.id; models.Page.findById(id, function(err, doc){ res.render('show_page', {page: doc}); }); }); // **** EDIT ROUTES **** router.get('/edit/:id', function(req, res){ var id = req.params.id; console.log(id); models.Page.findById(id, function(err, doc){ console.log(doc); res.render('edit', {page: doc}); }); }); router.post('/edit_submit/:id', function(req, res){ var id = req.params.id; var new_title = req.body.title; var new_body = req.body.body; console.log(req.body); models.Page.findByIdAndUpdate(id, {title: new_title, body: new_body }, function(err, docs){ // redirects to the wiki page res.redirect('/wiki/'+ docs.url_name +'?updated=true'); }); }); // **** DELETE ROUTE **** router.get('/delete/:id', function(req, res){ var id = req.params.id; models.Page.findByIdAndRemove(id, function(err, data){ res.redirect('/?deleted=true'); }); }); 

路由是在代码中设置的,因为节点会优先select首先遇到的路由,所以在设置路由时,顺序非常重要。
一个URL可能会匹配多个路由,特别是当使用捕获大量不同URL或静态路由的variables时。

说你的情况,你有一个url,看起来像

http://example.com/edit/1234

这个URL肯定会被这条路线所捕获

 router.get('/:url_name/:id' .... 

因为它与http://example.com/something/something布局相匹配,并且也会被以下路由捕获

 router.get('/edit/:id', .... 

因为它匹配http://example.com/edit/something布局。

什么路线实际上抓住了URL取决于它们在设置时遇到的顺序,无论哪个路由首先被声明,都会捕获该URL。

只是改变路线的顺序在大多数情况下将解决像这样的问题

 // if the URL matches, this will execute first router.get('/edit/:id', function(req, res){ // do stuff }); // You'll only get here if the URL doesn't match the above route router.get('/:url_name/:id', function(req, res){ // do stuff }); 

有一个解决方法,如果你不能交换周围的路线,使用next()callback,就像这样

 router.get('/:url_name/:id', function(req, res, next){ if ( req.params.url_name == 'edit' ) { next(); // this sends the request back to look for routes below this one }else{ // do stuff } }); router.get('/edit/:id', function(req, res){ // now we'll get here when the "url_name" is "edit" ... });