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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10020099/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 15:27:05  来源:igfitidea点击:

Express.js routing: optional splat param?

node.jsexpress

提问by Jesse

I have a route that looks like this:

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

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

however, this doesn't work - if I call path/foo/barit hits the route, but if I call path/foo, it doesn't.

但是,这不起作用 - 如果我调用path/foo/bar它会命中路线,但如果我调用path/foo它,则不会。

Is it possible to have an optional splat param, or do I have to use a regex to detect this?

是否可以有一个可选的 splat 参数,或者我是否必须使用正则表达式来检测这个?

Edit:

编辑

to be clearer, here are the requirements I'm trying to achieve:

更清楚地说,这里是我想要达到的要求:

  • the first and second params are required
  • the first param is static, the second is a named param.
  • any number of optionaladditional params can be appended and still hit the route.
  • 第一个和第二个参数是必需的
  • 第一个参数是静态的,第二个是命名参数。
  • 可以附加任意数量的可选附加参数并且仍然命中路由。

回答by Chris

This works for /path and /path/foo on express 4, note the *before ?.

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

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

回答by Andreas Hultgren

I just had the same problem and solved it. This is what I used:

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

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

This should work for path/meow, path/meow/voof, path/meow/voof/moo/etc...

这应该适用于path/meow, path/meow/voof, path/meow/voof/moo/etc...

It seems by dropping the /between ?and *, the last /becomes optional too while :optional?remains optional.

似乎通过删除/between?*,最后一个也/变成可选的,而:optional?仍然是可选的。

回答by Dave Ward

Will this do what you're after?

这会做你想要的吗?

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

More on Express' routing here, if you haven't looked: http://expressjs.com/guide/routing.html

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

回答by Jesse

Here's the current way I'm solving this problem, it doesn't appear that express supports any number of splat params with an optional named param:

这是我解决这个问题的当前方法,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
  }
});

I'd love to have this use named params for readability and consistency - if another answer surfaces that allows this I'll accept it.

我很乐意将这种名为 params 的用途用于可读性和一致性——如果另一个答案允许这样做,我会接受它。

回答by yaya

Suppose you have this url: /api/readFile/c:/a/a.txt

假设你有这个网址: /api/readFile/c:/a/a.txt

If you want req.params.pathto be c::

如果你想req.params.path成为c:

'/api/readFile/:path*

If you want req.params.pathto be c:/a/a.txt:

如果你想req.params.path成为c:/a/a.txt

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

回答by williamli

I got around this problem by using a combination of a middleware that add trailing slashes to url and router.get('/bar/*?', ..., which will pick up everything after /bar/, and return undefinedif it is just /bar/. If the visitor asked for /bar, the express-slashmiddleware will add a slash to the request and turns the request into /bar/.

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

回答by windmaomao

The above solutions using optional doesn't work in Express 4. And I tried couple of ways using search patterns, but not working either. And then I found this method and seems fired for unlimited nested path, http://expressjs.com/api.html#router

上述使用 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();
});

It's match all /bar, /bar/z, /bar/a/b/c etc. And after that, you can read req.originalUrl, since params are not filled, ex. you can try compare baseUrl and originalUrl to get the remaining path.

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