【问题标题】:ExpressJS Router is not handling root routesExpressJS 路由器不处理根路由
【发布时间】:2017-03-17 04:22:15
【问题描述】:

更新 2:我刚刚注意到,如果在应用程序文件上我更改了行:

app.use('/', home);

到:

app.use('/anything', home);

那么所有子路由“根”都可以正常工作。

更新 3:我刚刚意识到其他事情。 home.js 文件中的一个方法,由于我认为不相关,因此我最初没有在下面包含该方法,结果证明是问题的原因。

router.get('/:adventureId', (req, res) => {
   var data;
   //Irrelevant content that sets data as a JSON object.
   res.json(data);
});

事实证明,每个子路由“根”都经过这里,并且由于在其他路由上 AdventureId 未定义,因此数据只是一个空的 JSON 对象。

所以真正的问题是:如果这个路由器绑定到“/”而其他“根”绑定到“/adventure”和“/test”,为什么它们都通过“/:adventrueId” ?


我有一个非常简单的 ExpressJS 应用程序,在该应用程序上,除了 home 之外,每个路由中的所有“根”都没有被处理,并且它们总是在页面上显示一个空的 JSON 对象。

在一些帖子中提到这可能是一个缓存问题,因为这些路由总是返回 304 状态,但我尝试在 Chrome 上执行“空缓存和硬重新加载”,即使状态为 200,我仍然得到一个空白页面,上面显示一个空的 JSON 对象。我用 MS Edge 进行了尝试,得到了完全相同的行为。

这是我所拥有的:

在我的应用文件上

var app = express();

var home = require('./routes/home');
var adventure = require('./routes/adventure');
var test = require('./routes/test');

app.use('/', home);
app.use('/adventure', adventure);
app.use('/test', test);

在 home.js 文件中:

var express = require('express');
var router = express.Router();

router.get('/', (req, res) => {
   console.log("This works fine with http://localhost:3000.");
   res.render('home');
});

router.get('/:adventureId', (req, res) => {
   var data;
   //Irrelevant content that sets data as a JSON object.
   res.json(data);
});

module.exports = router;

在 Adventure.js 文件中:

var express = require('express');
var router = express.Router();

router.use('/:id', (req, res) => {
   console.log("This works fine with http://localhost:3000/adventure/5.");   
   next();
});

router.get('/:id', (req, res) => {
   console.log("This works fine with http://localhost:3000/adventure/5."); 
   res.render('adventure');
});

//I've also tried putting this before the other routes and the result is the same.
router.get('/', (req, res) => {
   console.log("This is never written in the console with http://localhost:3000/adventure.");
   res.send("This is never rendered in the page.");
});

在 test.js 文件上:

var express = require('express');
var router = express.Router();

router.use('/', (req, res) => {
    console.log("This is never written on the console with http://localhost:3000/test.");
    res.send("Hello from the test root route");
});

module.exports = router;

在 ExpressJS 路由器文档以及我发现的每一个博客和示例中,都说它应该是这样工作的,所以我真的很茫然。

谢谢。

【问题讨论】:

  • nodejs / express 版?
  • 为什么每个根端都是.
  • @Jérôme - 节点版本:7.0.0 和 Express 版本:4.14.1
  • @RIYAJKHAN - 这只是 console.log 中句子的结尾。当我在浏览器上输入它时,那里没有点。
  • 在向adventure 路由的根发出 GET 请求时,您是否收到了res.render('adventure')?如果是这样,请尝试将router.get('/') 部分移动到路由器文件的顶部,因为/:id 可以定义或不定义,路由器将为/ 处理它,:id 参数为空

标签: node.js express


【解决方案1】:

如果这个路由器绑定到“/”而其他“根”绑定到“/adventure”和“/test”,为什么它们都通过“/:adventrueId”?

因为 Express 不会根据哪个匹配 best 来匹配路由,它会匹配哪个匹配 first

在您的情况下,路由 /:advertureId/adventure/test 的路由之前声明。并且/adventure/test 都匹配/:advertureId,因此调用该路由的处理程序。

如果要防止这种情况,请先声明更具体的路线:

app.use('/adventure', adventure);
app.use('/test', test);
app.use('/', home);

【讨论】:

  • 确实,由于所有这些声明都被视为中间件,它们是在一个链中一个接一个地传递,直到发送响应或声明终止点
  • @robertklep - 你发布了你的答案,就像我在意识到这一点后输入我的一样,所以你得到它,因为先到先得:)
【解决方案2】:

经过多次更新,我对问题进行了几次更新,然后我终于明白了问题所在:

通过这样设置路由器:

app.use('/', home);
app.use('/adventure', adventure);
app.use('/game', gameService);
app.use('/test', test);

在具有此方法签名的“家庭”路由器上:

router.get('/:adventureId', (req, res) => {
   var data;
   //Irrelevant content that sets data as a JSON object.
   res.json(data);
});

每个子路由“根”都被解释为前一个方法的参数,所以:

/冒险
/测试
/任何东西

将被处理为:

adventrueId = 冒险
AdventureId = 测试
AdventureId = 任何东西

解决方案是这样做:

app.use('/adventure', adventure);
app.use('/game', gameService);
app.use('/test', test);
app.use('/', home);

现在一切正常。

【讨论】:

    猜你喜欢
    • 2017-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    • 2014-11-15
    相关资源
    最近更新 更多