Express.js маршрутизация: необязательный параметр splat?

У меня есть маршрут, который выглядит так:

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, или мне нужно использовать регулярное выражение для его обнаружения?

Edit

чтобы быть более ясными, вот требования, которые я пытаюсь достичь:

  • первый и второй параметры требуется
  • первый параметр статический, второй - именованный параметр.
  • любое количество необязательных дополнительных параметров может быть добавлено и по-прежнему попадает в маршрут.

Ответ 1

Это работает для /path и/path/foo on express 4, обратите внимание на * до ?.

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

Ответ 2

У меня была такая же проблема и она была решена. Это то, что я использовал:

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

Это должно работать для path/meow, path/meow/voof, path/meow/voof/moo/etc...

Кажется, отбрасывая / между ? и *, последний / становится необязательным, а :optional? остается необязательным.

Ответ 3

Будет ли это делать то, что вам нужно?

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

Больше на Express 'маршрутизация здесь, если вы не посмотрели: http://expressjs.com/guide/routing.html

Ответ 4

В данном способе я решаю эту проблему, не представляется, что express поддерживает любое количество параметров splat с необязательным именем param:

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

Мне бы хотелось, чтобы это использование называлось params для удобочитаемости и согласованности - если другие поверхности ответов, которые разрешают это, я буду принимать его.

Ответ 5

Вышеупомянутые решения с использованием опционального не работают в 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, так как params не заполнены, например. вы можете попробовать сравнить baseUrl и originalUrl, чтобы получить оставшийся путь.

Ответ 6

Я обошел эту проблему, используя комбинацию промежуточного программного обеспечения, которое добавляет косые черты в url и router.get('/bar/*?',..., которые будут собирать все после /bar/ и возвращать undefined если оно это просто /bar/. Если посетитель запросил /bar, промежуточное ПО express-slash добавит косую черту в запрос и превратит запрос в /bar/.

Ответ 7

Предположим, у вас есть этот URL: /api/readFile/c:/a/a.txt

Если вы хотите, чтобы req.params.path был c::

'/api/readFile/:path*

Если вы хотите, чтобы req.params.path был c:/a/a.txt:

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