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/
,