Mam trasę, która wygląda tak:
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
}
});
jednak to nie działa - jeśli nazywam path/foo/bar
to trafia w trasę, ale jeśli dzwonię path/foo
, nie działa.
Czy można mieć opcjonalny parametr splat, czy też muszę użyć wyrażenia regularnego, aby to wykryć?
Edycja :
żeby było jaśniej, oto wymagania, które staram się osiągnąć:
- wymagany jest pierwszy i drugi parametr
- pierwszy parametr jest statyczny, drugi to nazwany parametr.
- dowolna liczba opcjonalnych dodatkowych parametrów może być dołączona i nadal trafia na trasę.
'/path/:firstParam/*'
. Jeśli tego potrzebujesz, zrób'/path/:firstParam/:secondParam?/*'
./path/foo
(tak pierwotnie wyglądała moja trasa, zanim chciałem opcjonalnej ikony). Dodatkowo, w twoim drugim przykładzie, dodanie ikony faktycznie neguje opcjonalny drugi parametr -/path/foo
nie będzie pasował do twojego drugiego wzorca ( tak samo nie będzie/path/foo/bar
...) - jedna z bardziej irytujących części routera Express./path/:firstParam
i/path/:firstParam/:secondParam/
jako dwa oddzielne routery ze wspólnym kontrolerem. nie ma potrzeby, aby Twoje adresy URL były mylącen
punktów końcowych jest konieczne do zaprojektowania aplikacji - nie kieruję się tylko do 1-3 parametrów, może to być dowolna liczba, więc ograniczenie liczby parametrów nie wchodzi w grę (jasne, mógłbym utworzyć 10 punktów końcowych, ale praca ekspresowa nie jest lepsza niż robienie tego na trasie). Mogę użyć trasy regex, aby rozwiązać mój problem (co teraz robię), ale miałem nadzieję, że będę mieć czytelną opcję./path/:param(/:otherOptionalParam)
Odpowiedzi:
Działa to dla / path i / path / foo w express 4, zwróć uwagę na
*
poprzednią?
.router.get('/path/:id*?', function(req, res, next) { res.render('page', { title: req.params.id }); });
źródło
/path/foo/bar/bazzle
,req.params.id
będzie równefoo
ireq.params[0]
równe/bar/bazzle
, co może spowodować potknięcie niektórych osób. Roztwór czyszczący może być, aby zdefiniować ścieżkę/path/*?
, która w wyrazić 4 ustawireq.params[0]
sięfoo/bar/bazzle
, co jest chyba bliżej do tego, co szukasz./path/foo/bar
ale nie/path/foo
. Próbowałem,'/path/:id/*
ale*
wydaje się, że pasuje również do pustego ciągu.Po prostu miałem ten sam problem i rozwiązałem go. Oto, czego użyłem:
app.get('path/:required/:optional?*', ...)
To powinno działać na
path/meow
,path/meow/voof
,path/meow/voof/moo/etc
...Wydaje się, że porzucając
/
pomiędzy?
i*
, ostatni/
staje się również opcjonalny, podczas gdy:optional?
pozostaje opcjonalny.źródło
Czy to zrobi to, czego szukasz?
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 } });
Więcej o routingu Express tutaj, jeśli nie szukałeś: http://expressjs.com/guide/routing.html
źródło
/path/foo/bar
, ale nie/path/foo/bar/baz
-*
mecze splat.+
, które są niezbędne do tego, co robię - zdecydowanie rtfm, wydaje się, że o tym nie wspominam, więc może nie jest to możliwe ...Oto obecny sposób, w jaki rozwiązuję ten problem, nie wydaje się, aby express obsługuje dowolną liczbę parametrów splat z opcjonalnym nazwanym parametrem:
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 } });
Chciałbym, aby to użycie nazwano params dla czytelności i spójności - jeśli pojawi się inna odpowiedź, która na to pozwala, zaakceptuję ją.
źródło
Załóżmy, że masz ten adres URL:
/api/readFile/c:/a/a.txt
Jeśli chcesz
req.params.path
byćc:
:'/api/readFile/:path*
Jeśli chcesz
req.params.path
byćc:/a/a.txt
:'/api/readFile/:path([^/]*)'
źródło
Powyższe rozwiązania wykorzystujące opcjonalne nie działają w Express 4. Próbowałem kilku sposobów używając wzorców wyszukiwania, ale też nie działały. A potem znalazłem tę metodę i wydaje się, że uruchomiono nieograniczoną ścieżkę zagnieżdżoną, 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(); });
Dopasowuje wszystko / bar, / bar / z, / bar / a / b / c itd. A potem możesz przeczytać req.originalUrl, ponieważ parametry nie są wypełnione, np. możesz spróbować porównać baseUrl i originalUrl, aby uzyskać pozostałą ścieżkę.
źródło
Omówiłem ten problem, używając kombinacji oprogramowania pośredniczącego, które dodaje końcowe ukośniki do adresu URL i
router.get('/bar/*?', ...
, które odbierze wszystko po/bar/
i zwróci,undefined
jeśli jest tylko/bar/
. Jeśli odwiedzający poprosił o to/bar
,express-slash
oprogramowanie pośredniczące doda ukośnik do żądania i zamieni żądanie na/bar/
.źródło