106 votes

Routage par caractères génériques Express-js pour couvrir tout ce qui se trouve sous un chemin et l'inclut

J'essaye d'avoir une route qui couvre tout sous /foo y compris /foo lui-même. J'ai essayé d'utiliser /foo* qui fonctionnent pour tout sauf il ne correspond pas /foo . Observez :

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

Sorties :

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

Quelles sont mes options ? La meilleure solution que j'ai trouvée est d'acheminer /fo* ce qui, bien sûr, n'est pas très optimal car cela correspondrait à beaucoup trop de choses.

0 votes

Si vous interceptez tous les /foo* des routes comme celle-là, ne voulez-vous pas plutôt en faire un intergiciel ?

4 votes

Faites attention à ce que vous demandez : /foo* correspond à /foo/bar mais correspond également à /foolish ce qui n'était probablement pas votre intention.

125voto

serby Points 1425

Je pense que vous devrez avoir 2 routes. Si vous regardez la ligne 331 du routeur connect, l'astérisque (*) dans un chemin est remplacé par .+ et correspondra donc à 1 ou plusieurs caractères.

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

Si vous avez 2 routes qui effectuent la même action, vous pouvez faire ce qui suit pour la conserver SEC .

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

29voto

Johann Points 750

Le routeur de connexion a maintenant été supprimé ( https://github.com/senchalabs/connect/issues/262 ), l'auteur déclarant que vous devriez utiliser un framework au-dessus de connect (comme Express) pour le routage.

Express traite actuellement app.get("/foo*") comme app.get(/\/foo(.*)/) ce qui élimine la nécessité de deux routes distinctes. Ceci est en contraste avec la réponse précédente (se référant au routeur connect maintenant supprimé) qui indiquait que " * dans un chemin est remplacé par .+ ".

Mise à jour : Express utilise maintenant le module "path-to-regexp" (depuis Express 4.0.0) qui maintient le même comportement dans la version actuellement référencée. Je ne sais pas si la dernière version de ce module conserve ce comportement, mais pour l'instant cette réponse est valable.

14voto

Somo Points 805

Il n'est pas nécessaire d'avoir deux routes.

Il suffit d'ajouter (/*)? à la fin de votre path chaîne.

Par exemple, *`app.get('/hello/world(/)?' / ... /)`**

Voici un exemple entièrement fonctionnel. N'hésitez pas à le copier et le coller dans un fichier .js à exécuter avec node, et à jouer avec dans un navigateur (ou 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!'))

0 votes

Je ne sais pas pourquoi, mais cela n'a pas fonctionné pour moi. middleware : /template/:id(/*)? parent dir : /template/:id sous-directeur : /template/:id/edit les deux répertoires se déclencheront comme prévu, mais l'intergiciel ne se déclenchera pas du tout.

0 votes

J'ai trouvé... un logiciel médiateur router.use('/template/:id', ...) fonctionnera parfaitement

10voto

DrDimedrol Points 109

Dans le tableau, vous pouvez également utiliser les variables passées à req.params :

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

4voto

throbi Points 31

Pour ceux qui apprennent node/express (tout comme moi) : n'utilisez pas de routage sauvage si possible !

Je voulais également mettre en œuvre le routage pour GET /users/:id/whatever en utilisant le routage par caractères génériques. Voici comment j'en suis arrivé là.

Plus d'informations : https://blog.praveen.science/wildcard-routing-is-an-anti-pattern/

3 votes

Lien actuellement mort. Peut-être que c'était la même chose que : jonathanong.github.io/wildcard-routing-is-an-anti-pattern.html

0 votes

@RonBurk votre url semble être morte aussi Comment puis-je avoir un joker optionnel après un paramètre nommé ? "/quelque chose/:id(/*) ?" ne fonctionne pas

0 votes

Il sera probablement encore dans le cache de Google pour un petit moment : webcache.googleusercontent.com/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X