comment obtenir le chemin de la demande avec un objet de demande express


158

J'utilise express + node.js et j'ai un objet req, la requête dans le navigateur est / account mais lorsque je connecte req.path, j'obtiens '/' --- pas '/ account'.

  //auth required or redirect
  app.use('/account', function(req, res, next) {
    console.log(req.path);
    if ( !req.session.user ) {
      res.redirect('/login?ref='+req.path);
    } else {
      next();
    }
  });

req.path est / quand il devrait être / account ??


2
TypeError: Cannot read property 'path' of undefined
chovy

req.route.path est correct et documenté ici . Quelle version d'express utilisez-vous?
zemirco

J'ai le même problème. req.routen'est pas défini. J'utilise express 3.4.4. Qu'est-ce qui peut rendre la route indéfinie?
davidpfahler

@vinayr req.route.path me donne toujours / create au lieu de / quiz / create, qui est l'URL complète
Sandip Subedi

C'est un comportement intentionnel. Et vous devriez l'accepter. Votre gestionnaire ne doit pas se soucier du chemin complet, mais uniquement de la partie «locale» du chemin. C'est la partie après le chemin sur lequel il a été monté. Cela rend la fonction de gestionnaire plus facile à réutiliser dans d'autres contextes.
Stijn de Witt

Réponses:


234

Après avoir joué un peu moi-même, vous devriez utiliser:

console.log(req.originalUrl)


3
Je pense que cela a quelque chose à voir avec le positionnement du middleware, mais vous avez raison, cela n'a pas de sens.
Menztrual

1
C'est définitivement le middleware. Cela se produit également avec des routeurs supplémentaires dans Express 4. Lorsque l'un ou l'autre est monté hors d'un chemin donné, à l'intérieur de lui-même, il peut prétendre qu'il est hors de la racine. C'est bien pour l'isolement, mais délicat lorsque vous ne savez pas comment obtenir la valeur totale d'origine. Merci d'avoir publié ceci!
juanpaco

3
Quiconque arrive ici sous 4.0, req.url est conçu pour être modifiable par le middleware à des fins de réacheminement, et req.path peut manquer de points de montage selon l'endroit où il est appelé. expressjs.com/en/api.html#req.originalUrl
Christian Davis

3
Si vous ne voulez pas que la chaîne de requête soit incluse:const path = req.originalUrl.replace(/\?.*$/, '');
Adam Reis

1
Attention: Il s'agit d'une réponse trompeuse, basée sur la question OP. Cela renverra également la chaîne de requête (par exemple? A = b & c = 5) si elle était présente. Voir expressjs.com/en/api.html#req.originalUrl
Ciabaros

60

Dans certains cas, vous devez utiliser:

req.path

Cela vous donne le chemin, au lieu de l'URL demandée complète. Par exemple, si vous n'êtes intéressé que par la page demandée par l'utilisateur et non par tous les types de paramètres, l'url:

/myurl.htm?allkinds&ofparameters=true

req.path vous donnera:

/myurl.html

1
Veillez à ce que si vous effectuez des vérifications par rapport à cette URL, incluez également une vérification pour une barre oblique finale si elle est valide dans votre application. (c'est-à-dire que la vérification /demodevrait également potentiellement vérifier /demo/).
Vinay le

Si vous ne voulez pas que la chaîne de requête soit incluse: const path = req.originalUrl.replace (/\?.*$/, '');
Adam Reis

req.pathest le raccourci de url.parse(req.url).pathnameet cela devrait être la réponse acceptée
sertsedat

1
@sertsedat Incorrect. req.pathvous donne le chemin d'accès relatif à l'endroit où votre application est montée. S'il est monté à la racine, cela est correct, mais pour un chemin /my/path, dans une application montée sur /my, req.urldonnera /path.
Stijn de Witt

21

Pour compléter, voici un exemple développé à partir de la documentation, qui englobe bien tout ce que vous devez savoir sur l'accès aux chemins / URL dans tous les cas avec express:

app.use('/admin', function (req, res, next) { // GET 'http://www.example.com/admin/new?a=b'
  console.dir(req.originalUrl) // '/admin/new?a=b' (WARNING: beware query string)
  console.dir(req.baseUrl) // '/admin'
  console.dir(req.path) // '/new'
  console.dir(req.baseUrl + req.path) // '/admin/new' (full path without query string)
  next()
})

Basé sur: https://expressjs.com/en/api.html#req.originalUrl

Conclusion: comme l' indique la réponse de c1moore ci-dessus, utilisez:

var fullPath = req.baseUrl + req.path;


9
//auth required or redirect
app.use('/account', function(req, res, next) {
  console.log(req.path);
  if ( !req.session.user ) {
    res.redirect('/login?ref='+req.path);
  } else {
    next();
  }
});

req.path est / quand il devrait être / account ??

La raison en est qu'Express soustrait le chemin sur lequel votre fonction de gestionnaire est montée, ce qui est '/account'dans ce cas.

Pourquoi font-ils cela?

Parce que cela facilite la réutilisation de la fonction de gestionnaire. Vous pouvez créer une fonction de gestionnaire qui effectue différentes choses pour req.path === '/'et req.path === '/goodbye'par exemple:

function sendGreeting(req, res, next) {
  res.send(req.path == '/goodbye' ? 'Farewell!' : 'Hello there!')
}

Ensuite, vous pouvez le monter sur plusieurs points de terminaison:

app.use('/world', sendGreeting)
app.use('/aliens', sendGreeting)

Donnant:

/world           ==>  Hello there!
/world/goodbye   ==>  Farewell!
/aliens          ==>  Hello there!
/aliens/goodbye  ==>  Farewell!

9

Si vous voulez vraiment obtenir uniquement "chemin" sans chaîne de requête, vous pouvez utiliser la urlbibliothèque pour analyser et obtenir uniquement une partie du chemin de l'url.

var url = require('url');

//auth required or redirect
app.use('/account', function(req, res, next) {
    var path = url.parse(req.url).pathname;
    if ( !req.session.user ) {
      res.redirect('/login?ref='+path);
    } else {
      next();
    }
});

c'est exactement ce que je veux. Utilisez-le avec req.query.refsi la connexion est réussie
Ryan Wu

Cela fonctionne bien avec le code universel car il est conforme aux spécifications d' emplacement . Moins d'éléments à retenir et des tests unitaires plus faciles sur le client et le serveur.
cchamberlain

req.pathest juste un alias poururl.parse(req.url).pathname
mhodges

8

Pour la version 4.x, vous pouvez désormais utiliser req.baseUrlen plus de req.pathpour obtenir le chemin complet. Par exemple, l'OP ferait maintenant quelque chose comme:

//auth required or redirect
app.use('/account', function(req, res, next) {
  console.log(req.baseUrl + req.path);  // => /account

  if(!req.session.user) {
    res.redirect('/login?ref=' + encodeURIComponent(req.baseUrl + req.path));  // => /login?ref=%2Faccount
  } else {
    next();
  }
});

5

req.route.path fonctionne pour moi

var pool = require('../db');

module.exports.get_plants = function(req, res) {
    // to run a query we can acquire a client from the pool,
    // run a query on the client, and then return the client to the pool
    pool.connect(function(err, client, done) {
        if (err) {
            return console.error('error fetching client from pool', err);
        }
        client.query('SELECT * FROM plants', function(err, result) {
            //call `done()` to release the client back to the pool
            done();
            if (err) {
                return console.error('error running query', err);
            }
            console.log('A call to route: %s', req.route.path + '\nRequest type: ' + req.method.toLowerCase());
            res.json(result);
        });
    });
};

après l'exécution, je vois ce qui suit dans la console et j'obtiens un résultat parfait dans mon navigateur.

Express server listening on port 3000 in development mode
A call to route: /plants
Request type: get
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.