NodeJS Express.js路由:可选的splat参数

brtdzjyr  于 2023-04-20  发布在  Node.js
关注(0)|答案(8)|浏览(155)

我有一条路线,看起来像这样:

app.all('/path/:namedParam/*splat?',function(req,res,next){
  if(!req.params.length){
    // do something when there is no splat
  } else {
    // do something with splat
  }
});

但是,这不起作用-如果我调用path/foo/bar,它会到达路由,但如果我调用path/foo,它不会。
有没有可能有一个可选的splat参数,或者我必须使用正则表达式来检测它?

编辑

更清楚地说,以下是我试图实现的要求:

  • 第一个和第二个参数是必填
  • 第一个参数是静态的,第二个是命名的参数。
  • 可以附加任意数量的 * 可选 * 附加参数并且仍然命中路由。
vc9ivgsu

vc9ivgsu1#

这适用于express 4上的/path和/path/foo,注意*?之前。

router.get('/path/:id*?', function(req, res, next) {
    res.render('page', { title: req.params.id });
});
cfh9epnr

cfh9epnr2#

我刚刚遇到了同样的问题,并解决了它。这是我使用的:

app.get('path/:required/:optional*?', ...)

这应该适用于path/meowpath/meow/voofpath/meow/voof/moo/etc ...
似乎通过删除?*之间的/,最后一个/也成为可选的,而:optional?仍然是可选的。

mo49yndu

mo49yndu3#

这能满足你的要求吗

app.all('/path/:namedParam/:optionalParam?',function(req,res,next){
  if(!req.params.optionalParam){
    // do something when there is no optionalParam
  } else {
    // do something with optionalParam
  }
});

更多关于快递的路由在这里,如果你还没有看:http://expressjs.com/guide/routing.html

k75qkfdt

k75qkfdt4#

假设你有这个URL:/api/readFile/c:/a/a.txt
如果你想让req.params.path变成c:

'/api/readFile/:path*

如果您希望req.params.path成为c:/a/a.txt

'/api/readFile/:path([^/]*)'
wbrvyc0a

wbrvyc0a5#

下面是我解决这个问题的方法,express似乎不支持任何数量的splat参数和可选的命名参数:

app.all(/\/path\/([^\/]+)\/?(.+)?/,function(req,res,next){
  // Note: this is all hacked together because express does not appear to support optional splats.
  var params = req.params[1] ? [req.params[1]] : [],
      name = req.params[0];
  if(!params.length){
    // do something when there is no splat
  } else {
    // do something with splat
  }
});

为了可读性和一致性,我希望使用命名参数-如果另一个答案允许这样做,我会接受它。

sxissh06

sxissh066#

上面使用optional的解决方案在Express 4中不起作用。我尝试了几种使用搜索模式的方法,但都不起作用。然后我发现这个方法似乎被无限嵌套路径解雇了,http://expressjs.com/api.html#router

// this will only be invoked if the path starts with /bar from the mount point
router.use('/bar', function(req, res, next) {
  // ... maybe some additional /bar logging ...

  // to get the url after bar, you can try
  var filepath = req.originalUrl.replace(req.baseUrl, "");

  next();
});

它匹配所有/bar,/bar/z,/bar/a/b/c等。之后,您可以读取req.originalUrl,因为参数没有填写,例如。您可以尝试比较baseUrl和originalUrl以获得剩余的路径。

6ioyuze2

6ioyuze27#

我通过使用中间件的组合来解决这个问题,中间件在url和router.get('/bar/*?', ...后面添加斜杠,它将拾取/bar/之后的所有内容,如果只是/bar/,则返回undefined。如果访问者请求/bar,则express-slash中间件将在请求中添加斜杠,并将请求转换为/bar/

inn6fuwd

inn6fuwd8#

要使任何尾随路径在命名参数中结束,可以在星号上添加圆括号;

router.get('/path/:trailing(*)?', function(req, res, next) {
  console.log(req.params.trailing);
  // ...
});

对于/path/level1,这将使trailing参数设置为level1,而对于/path/level1/level2/level3,则设置为level1/level2/level3

相关问题