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

时间:2014-05-24 17:04:06

标签: javascript node.js express mongoose

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

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});
    });

});

我正在做的是为具有id params匹配id的Page创建一个编辑页面视图。 这一直有效......

我不得不添加这条新路线:

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 /:id页面路由不会收集id参数(req.params.id)。

我迷失了为什么这不起作用以及我应该开始尝试调试的地方,因为我没有收到任何错误,它仍然会将我带到我的edit /:id页面,但是当我在console.log(id)时)我没有收到任何价值,甚至没有收到任何价值。此外,我找不到我传递到编辑视图的{page:doc}。

如果有人可以提供洞察力或开始寻求调试的地方,我会很感激。只是提醒一下,当我没有:url_name /:id route active时,edit /:id路由可以正常工作(req.params.id获取id)。

当前路线 -

我在app.js中添加了var wiki_routes = require('./routes/wiki');,并且在那条路线中我有:

// **** 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');
    });
});

1 个答案:

答案 0 :(得分:2)

路由在代码中出现时设置,因为节点将优先考虑它首先遇到的路线,因此在设置路线时,命令很重要很多
URL可能会匹配多个路由,尤其是在使用捕获大量不同URL或静态路由等的变量时。

假设你的网址看起来像

http://example.com/edit/1234

这条路线肯定会被这条路线抓住

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()回调来交换路线,则会有一种解决方法,就像这样

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" ...
});