Instradamento con caratteri jolly Express-js per coprire tutto sotto e incluso un percorso


96

Sto cercando di avere un percorso che copra tutto ciò che è /foocompreso /foo. Ho provato a utilizzare /foo*quale lavoro per tutto tranne che non corrisponde /foo. Osservare:

var express = require("express"),
    app = express.createServer();

app.get("/foo*", function(req, res, next){
  res.write("Foo*\n");
  next();
});

app.get("/foo", function(req, res){
  res.end("Foo\n");
});

app.get("/foo/bar", function(req, res){
  res.end("Foo Bar\n");
});

app.listen(3000);

Uscite:

$ curl localhost:3000/foo
Foo
$ curl localhost:3000/foo/bar
Foo*
Foo Bar

Quali sono le mie opzioni? La cosa migliore che ho trovato è quella di tracciare /fo*che ovviamente non è molto ottimale in quanto corrisponderebbe troppo.


Se /foo*stai intercettando tutte le rotte in questo modo, non vuoi renderlo invece middleware?
Raynos

3
Fai attenzione a ciò che chiedi: /foo*partite /foo/barma anche partite /foolishche probabilmente non intendevi.
Wyck

Risposte:


111

Penso che dovrai avere 2 percorsi. Se guardi la riga 331 del router di connessione, * in un percorso viene sostituito con. + Quindi corrisponderà a 1 o più caratteri.

https://github.com/senchalabs/connect/blob/master/lib/middleware/router.js

Se hai 2 percorsi che eseguono la stessa azione, puoi fare quanto segue per mantenerlo ASCIUTTO .

var express = require("express"),
    app = express.createServer();

function fooRoute(req, res, next) {
  res.end("Foo Route\n");
}

app.get("/foo*", fooRoute);
app.get("/foo", fooRoute);

app.listen(3000);

101
app.get(["/foo", "/foo*"], /* function */);potrebbe essere anche preferenziale!
Chris Foster

9
Anche il passaggio di una serie di stringhe è preferenziale per me. Sfortunatamente: il passaggio di un array a app.VERB () è deprecato e verrà rimosso in 4.0
CodeWarrior

10
Il passaggio di un array di stringhe è stato ripristinato in Express 4.9.1.
Pete TNT

30

Il router di connessione è stato ora rimosso ( https://github.com/senchalabs/connect/issues/262 ), l'autore afferma che dovresti utilizzare un framework sopra connect (come Express) per il routing.

Express attualmente tratta app.get("/foo*") come app.get(/\/foo(.*)/), eliminando la necessità di due percorsi separati. Questo è in contrasto con la risposta precedente (riferendosi al router di connessione ora rimosso) che affermava che " *in un percorso è sostituito con .+".

Aggiornamento: Express ora utilizza il modulo "path-to-regexp" (da Express 4.0.0) che mantiene lo stesso comportamento nella versione attualmente a cui si fa riferimento. Non mi è chiaro se l'ultima versione di quel modulo mantenga il comportamento, ma per ora questa risposta è valida.


Quindi dovremmo usare. + O *?
Tyler Langan

2
Utilizzare /\/foo(.+)/se si desidera una corrispondenza /fooseguita da uno o più caratteri e /foo*o /\/foo(.*)/se si desidera trovare una corrispondenza /fooseguita da zero o più caratteri.
Johann

12

Non è necessario avere due percorsi.

Aggiungi semplicemente (/*)?alla fine della pathstringa.

Per esempio, app.get('/hello/world(/*)?' /* ... */)

Ecco un esempio completamente funzionante, sentiti libero di copiarlo e incollarlo in un file .js da eseguire con node e giocare con esso in un browser (o curl):

const app = require('express')()

// will be able to match all of the following
const test1 = 'http://localhost:3000/hello/world'
const test2 = 'http://localhost:3000/hello/world/'
const test3 = 'http://localhost:3000/hello/world/with/more/stuff'

// but fail at this one
const failTest = 'http://localhost:3000/foo/world'

app.get('/hello/world(/*)?', (req, res) => res.send(`
    This will match at example endpoints: <br><br>
    <pre><a href="${test1}">${test1}</a></pre>
    <pre><a href="${test2}">${test2}</a></pre>
    <pre><a href="${test3}">${test3}</a></pre>

    <br><br> Will NOT match at: <pre><a href="${failTest}">${failTest}</a></pre>
`))

app.listen(3000, () => console.log('Check this out in a browser at http://localhost:3000/hello/world!'))

9

In array puoi anche usare le variabili che passano a req.params:

app.get(["/:foo", "/:foo/:bar"], /* function */);

3

Per coloro che stanno imparando node / express (proprio come me): non usare il jolly routing se possibile!

Volevo anche implementare il routing per GET / users /: id / qualunque cosa usando il routing con caratteri jolly. Ecco come sono arrivato qui.

Fortunatamente ho trovato anche questo articolo: http://www.jongleberry.com/wildcard-routing-is-an-anti-pattern.html

Salute, Robert


2
Link attualmente morto. Forse era lo stesso di: jonathanong.github.io/wildcard-routing-is-an-anti-pattern.html
Ron Burk

@RonBurk anche il tuo URL sembra essere morto .. Come posso avere un carattere jolly opzionale dopo un parametro denominato? "/ qualcosa /: id (/ *)?" non funziona ..
Soichi Hayashi

Probabilmente sarà ancora nella cache di Google per un po ': webcache.googleusercontent.com/…
Ron Burk

esiste un'alternativa al routing con caratteri jolly se non ho idea di cosa viene dopo la parte iniziale dell'URL?
Michael

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.