未传递url param时不会调用Express路由

Bri*_*sad 4 node.js express

我的server.js中有以下代码用于路由中间件:

app.use('/users', require('./routes/user.routes'));
app.use((req, res) => res.status(404).json({code: 404, message: 'HTTP 404 Not Found'}));
Run Code Online (Sandbox Code Playgroud)

以下是我的user.routes.js代码

router.get('/admin/:id', (req, res) => {
    return userController.findUserById(req, res);
});
Run Code Online (Sandbox Code Playgroud)

它只要我给它工作正常:localhost:8080/users/admin/123 但是当我给你的网址没有id localhost:8080/users/admin /

它给我发了这样的信息: {"code":404,"message":"HTTP 404 Not Found"}

在我看来,它应该指引我走正确的路线.我错过了什么吗?

Moh*_*waj 7

如果您想让id参数可选,您可以?在路由处理程序中添加一个参数:

router.get('/admin/:id?', (req, res) => {
    return userController.findUserById(req, res);
});
Run Code Online (Sandbox Code Playgroud)

现在,无论是/admin/123/admin会打这个相同的路线.但是如果没有id传递,你的代码可能会失败.如果是这种情况,您应指定2条不同的路线:

router.get('/admin', (req, res) => {
    return userController.findUserById(req, res);
});


router.get('/admin/:id?', (req, res) => {
    return userController.findDefaultUser(req, res);
});
Run Code Online (Sandbox Code Playgroud)

  • 这完美地工作,在这种情况下不需要正则表达式。 (2认同)

ski*_*tle 5

我相信您可以通过提供自定义验证器来使其工作:

router.get('/admin/:id(\\d{0,})', (req, res) => {
    ...
});
Run Code Online (Sandbox Code Playgroud)

我的验证器检查id0 或更多数字,这将匹配一个空字符串。如果您id不是数字,那么您必须相应地调整正则表达式。请注意,Express 使用了一种特殊的正则表达式语法,它的规则与普通的 JavaScript RegExp 略有不同,例如在 Express 4 中你不能使用 use*所以我不得不使用它{0,}(参见https://github.com/expressjs/express /issues/2495)。

更新

使用?Mohit Bhardwaj 建议的 a 是一个更简单的解决方案,但这些方法之间存在细微差别。使用我上面你建议的验证仍然会收到一个idPARAM但是这将是一个空字符串,而与?id不会出现在params所有。这是否重要取决于您如何使用它。

还值得注意的是,使用 a?也将允许/users/admin匹配,而没有尾部斜杠。

如果您不关心将id字符串验证为路由匹配的一部分,那么我认为使用?将是可行的方法。