2012-04-04 18 views
58

Ho un percorso che assomiglia a questo:Instradamento Express.js: param param opzionale?

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

tuttavia, questo non funziona - se chiamo path/foo/bar colpisce il percorso, ma se chiamo path/foo, non è così.

E 'possibile avere un parametro splat opzionale o devo usare una regex per rilevare questo?

Edit:

di essere più chiaro, ecco i requisiti che sto cercando di realizzare:

  • il primo e secondo params sono richiesto
  • il primo parametro è statica , il secondo è un param nominato.
  • un numero qualsiasi di facoltativo parametri aggiuntivi possono essere aggiunti e continuano a raggiungere la rotta.
+1

cosa stai cercando di fare?se non hai bisogno di sapere splat, basta fare ''/ percorso /: firstParam/*''. Se ti serve, fai ''/ percorso /: firstParam /: secondParam?/*''. –

+0

Sto cercando di avere lo splat facoltativo - il primo esempio che hai fornito non corrispondeva a '/ path/foo', (questo è il mio percorso originariamente sembrava prima che volessi uno splat opzionale). Inoltre, nel tuo secondo esempio, l'aggiunta dello splat nega in realtà il secondo param opzionale - '/ path/foo' non corrisponderà al tuo secondo pattern (nemmeno'/path/foo/bar' per quella questione ...) - uno di le parti più fastidiose del router espresso. – Jesse

+1

personalmente andrei solo per '/ path /: firstParam' e'/path /: firstParam /: secondParam/'come due router separati con un controller condiviso. non c'è bisogno di rendere i propri URL confusi –

risposta

66

Questo funziona per/path e/path/foo su express 4, nota * prima di ?.

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

Nota che mentre funziona, se visiti '/ percorso/foo/bar/bazzle',' req.params.id' sarà uguale a 'foo', e 'req.params [0]' sarà uguale a '/ bar/bazzle', che potrebbe far inciampare alcune persone. Una soluzione più pulita può essere quella di definire il percorso come '/ percorso/*?', Che in espresso 4 imposterà 'req.params [0]' a 'foo/bar/bazzle', che è probabilmente più vicino a quello che sei cercando. – Jesse

12

Questo farà ciò che cerchi?

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

Altro su Express' di routing qui, se non hai guardato: http://expressjs.com/guide/routing.html

+1

Questa soluzione corrisponde a '/ percorso/foo/bar', ma non'/percorso/foo/bar/baz' - il '*' splat corrisponde a '. +' , che è necessario per quello che sto facendo - ho sicuramente rtfm, non sembra menzionarlo, quindi forse non è possibile ... – Jesse

2

Ecco il modo corrente sto risolvere questo problema, non sembra che Express supporta un numero illimitato di params splat con un optional param nome:

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

mi piacerebbe avere questo uso di nome params per la leggibilità e la coerenza - se un altro superfici di risposta che permette questo io ti accettano.

62

Ho appena avuto lo stesso problema e risolto. Questo è quello che ho usato:

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

Questo dovrebbe funzionare per path/meow, path/meow/voof, path/meow/voof/moo/etc ...

Sembra facendo cadere il / tra il ? e *, l'ultimo / diventa facoltativo troppo mentre :optional? rimane facoltativa .

+0

Cool! Ho appena testato questo (in Express 3.0.0, non ho testato in 2.x) e funziona. Questo è decisamente più pulito del mio hack RegEx. – Jesse

+5

Sai dove posso leggere di più su queste parole chiave predefinite? –

+7

In espresso 4.0x questo non sembra funzionare più – regretoverflow

0

Le soluzioni di cui sopra con l'opzione non funzionano in Express 4. E ho provato un paio di modi utilizzando modelli di ricerca, ma non funziona neanche. E poi ho trovato questo metodo e sembra licenziato per un numero illimitato percorso nidificato, 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(); 
}); 

E 'partita tutti/bar,/bar/z,/bar/a/b/c, ecc E dopo che, si può leggere req.originalUrl, poiché i parametri non sono riempiti, es. puoi provare a confrontare baseUrl e originalUrl per ottenere il percorso rimanente.