2012-04-04 11 views
58

Ich habe einen Weg, der wie folgt aussieht:Express.js Routing: Optional spuckt param?

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

aber das funktioniert nicht - wenn ich path/foo/bar nennen trifft es die Strecke, aber wenn ich path/foo nennen, es funktioniert nicht.

Ist es möglich, einen optionalen Splat-Parameter zu haben, oder muss ich einen Regex verwenden, um dies zu erkennen?

bearbeiten:

seine klare, hier sind die Anforderungen, die ich zu erreichen bin versucht:

  • der erste und zweiter params sind erforderlich
  • die erste param statisch , der zweite ist ein benannter Param.
  • eine beliebige Anzahl von optional zusätzliche Parameter können angehängt werden und immer noch die Route.
+1

Was versuchen Sie zu tun?Wenn Sie Splat nicht wissen müssen, tun Sie einfach "/ path /: firstParam/*". Wenn Sie es brauchen, tun Sie "/ path /: firstParam /: secondParam?/*". –

+0

Ich suche nach dem Splat optional - das erste Beispiel, das du gabst, würde nicht mit '/ path/foo' übereinstimmen (so sah meine Route ursprünglich aus, bevor ich einen optionalen Splat wollte). Darüber hinaus, in Ihrem zweiten Beispiel, das Hinzufügen der Splat negiert tatsächlich die optionale zweite Parameter - '/ Pfad/foo' wird nicht mit Ihrem zweiten Muster (auch nicht'/Pfad/foo/bar 'für diese Angelegenheit ...) - einer von die nervigeren Teile von Express 'Router. – Jesse

+1

persönlich würde ich nur für '/ Pfad /: FirstParam' und'/Pfad /: FirstParam /: SecondParam/'als zwei separate Router mit einem gemeinsamen Controller gehen. keine Notwendigkeit, Ihre URLs verwirrend zu machen –

Antwort

66

Dies funktioniert für/Pfad und/Pfad/foo auf Express 4, beachten Sie die * vor ?.

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

Beachten Sie, dass, während dies funktioniert, wenn Sie '/ Pfad/foo/bar/bazzle' besuchen, 'req.params.id' gleich' foo', und 'req.params [0]' wird gleich '/ bar/bazzle' sein, was einige Leute stolpern könnte. Eine sauberere Lösung könnte darin bestehen, den Pfad als '/ path/*?' Zu definieren, was in Express 4 'req.params [0]' auf 'foo/bar/bazzle' setzt, was wahrscheinlich näher an dem liegt, was Sie sind Auf der Suche nach. – Jesse

12

Wird dies tun, wonach Sie suchen?

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

Mehr auf Express' hier das Routing, wenn Sie nicht ausgesehen haben: http://expressjs.com/guide/routing.html

+1

Diese Lösung würde '/ path/foo/bar', aber nicht'/path/foo/bar/baz' entsprechen - das '*' splat passt '. +' , das ist notwendig für das, was ich tue - ich habe definitiv rtfm, scheint es nicht zu erwähnen, also vielleicht ist es nicht möglich ... – Jesse

2

Hier ist die aktuelle Art, wie ich dieses Problem habe lösen, ist es nicht, dass die ausdrückliche scheint unterstützt eine beliebige Anzahl von Splat params mit einem optionalen Namen 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 
    } 
}); 

ich würde gerne diese Anwendung namens params für Lesbarkeit und Konsistenz haben - wenn eine andere Antwort Oberflächen, die dies ermöglicht ich es akzeptieren werde.

62

Ich hatte gerade das gleiche Problem und löste es. Dies ist, was ich verwendet:

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

Diese für path/meow funktionieren sollte, path/meow/voof, path/meow/voof/moo/etc ...

Es scheint, durch die / zwischen ? und * fallen, der letzte / wird auch optional während :optional? bleibt optional .

+0

Cool! Ich habe das gerade getestet (in Express 3.0.0, nicht in 2.x getestet) und es funktioniert. Das ist definitiv sauberer als mein RegEx-Hack. – Jesse

+5

Wissen Sie, wo ich mehr über diese vordefinierten Keywords lesen kann? –

+7

In express 4.0x scheint das nicht mehr zu funktionieren – regretoverflow

0

Die obigen Lösungen mit optionalen funktioniert nicht in Express 4. Und ich habe versucht, einige Möglichkeiten mit Suchmuster, aber auch nicht funktioniert. Und dann fand ich diese Methode und scheint für eine unbegrenzte Anzahl verschachtelten Pfad abgefeuert, 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(); 
}); 

Es ist Spiel alle/Bar,/bar/z,/bar/a/b/c etc. Und danach können Sie lesen, req.originalUrl, da Params nicht gefüllt sind, z. Sie können versuchen, baseUrl und originalUrl zu vergleichen, um den verbleibenden Pfad zu erhalten.