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

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

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

Редактировать:

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

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

8 ответов

Решение

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

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

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

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

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

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

Будет ли это делать то, что вы после?

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

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

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

'/api/readFile/:path*

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

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

Вот текущий способ решения этой проблемы, но не похоже, что Express поддерживает любое количество параметров в виде аргумента с необязательным именем:

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 для удобочитаемости и согласованности - если появится другой ответ, который позволит это, я приму это.

Чтобы любой конечный путь попадал в именованный параметр, вы можете добавить круглые скобки к звездочке;

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

Это для/path/level1имел быtrailingпараметр установлен наlevel1, и для/path/level1/level2/level3кlevel1/level2/level3.

Вышеуказанные решения с использованием опциональных не работают в Express 4. И я попробовал несколько способов, используя шаблоны поиска, но тоже не работал. А потом я нашел этот метод и, похоже, запущен для неограниченного вложенного пути, http://expressjs.com/api.html

// 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, чтобы получить оставшийся путь.

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

Другие вопросы по тегам