Enrutamiento comodín Express-js para cubrir todo lo que se encuentra debajo de una ruta incluida


96

Estoy tratando de tener una ruta que cubra todo, /fooincluido él /foomismo. He intentado usar /foo*which work para todo, excepto que no coincide /foo. Observar:

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

Salidas:

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

¿Cuáles son mis opciones? Lo mejor que se me ha ocurrido es una ruta /fo*que, por supuesto, no es muy óptima, ya que coincidiría demasiado.


Si intercepta todas las /foo*rutas así, ¿no quiere convertirlo en middleware?
Raynos

3
Tenga cuidado con lo que pide: /foo*coincidencias /foo/barpero también coincidencias /foolishque probablemente no pretendía.
Wyck

Respuestas:


111

Creo que tendrás que tener 2 rutas. Si observa la línea 331 del enrutador de conexión, el * en una ruta se reemplaza con. +, Por lo que coincidirá con 1 o más caracteres.

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

Si tiene 2 rutas que realizan la misma acción, puede hacer lo siguiente para mantenerla SECA .

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 */);¡También podría ser preferencial!
Chris Foster

9
Pasar una serie de cadenas también es preferencial para mí. Desafortunadamente: pasar una matriz a app.VERB () está obsoleto y se eliminará en 4.0
CodeWarrior

10
El paso de una matriz de cadenas se ha restaurado en Express 4.9.1.
Pete TNT

30

El enrutador de conexión ahora se ha eliminado ( https://github.com/senchalabs/connect/issues/262 ), el autor afirma que debe usar un marco en la parte superior de la conexión (como Express) para el enrutamiento.

Express actualmente trata app.get("/foo*") como app.get(/\/foo(.*)/), eliminando la necesidad de dos rutas separadas. Esto contrasta con la respuesta anterior (refiriéndose al enrutador de conexión ahora eliminado) que decía que " *en una ruta se reemplaza con .+".

Actualización: Express ahora usa el módulo "path-to-regexp" (desde Express 4.0.0) que mantiene el mismo comportamiento en la versión actualmente referenciada. No me queda claro si la última versión de ese módulo mantiene el comportamiento, pero por ahora esta respuesta se mantiene.


Entonces, ¿deberíamos usar. + O *?
Tyler Langan

2
Úselo /\/foo(.+)/si desea hacer coincidir /fooseguido de uno o más caracteres, /foo*o /\/foo(.*)/si desea hacer coincidir /fooseguido de cero o más caracteres.
Johann

12

No es necesario tener dos rutas.

Simplemente agregue (/*)?al final de su pathcadena.

Por ejemplo, app.get('/hello/world(/*)?' /* ... */)

Aquí hay un ejemplo completamente funcional, siéntase libre de copiar y pegar esto en un archivo .js para ejecutarlo con el nodo y jugar con él en un navegador (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

En la matriz también puede usar variables que pasan a req.params:

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

3

Para aquellos que están aprendiendo node / express (como yo): ¡no use el enrutamiento comodín si es posible!

También quería implementar el enrutamiento para GET / users /: id / anything usando el enrutamiento comodín. Así es como llegué aquí.

Afortunadamente también he encontrado este artículo: http://www.jongleberry.com/wildcard-routing-is-an-anti-pattern.html

Saludos, Robert


2
Link actualmente muerto. Quizás era lo mismo que: jonathanong.github.io/wildcard-routing-is-an-anti-pattern.html
Ron Burk

@RonBurk, su URL también parece estar muerta. ¿Cómo puedo tener un comodín opcional después de un parámetro con nombre? "/ algo /: id (/ *)?" no funciona ..
Soichi Hayashi

Probablemente todavía estará en la caché de Google por un tiempo: webcache.googleusercontent.com/…
Ron Burk

¿Existe una alternativa al enrutamiento comodín si no tengo idea de lo que viene después de la parte inicial de la URL?
Michael

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.