come ottenere il percorso della richiesta con l'oggetto req express


158

Sto usando express + node.js e ho un oggetto req, la richiesta nel browser è / account ma quando registro req.path ottengo '/' --- not '/ 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 è / quando dovrebbe essere / account ??


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

req.route.path è corretto e documentato qui . Quale versione di Express stai usando?
zemirco,

Sto avendo lo stesso problema. req.routenon è definito. Sto usando express 3.4.4. Cosa può causare la definizione del percorso?
davidpfahler,

@vinayr req.route.path mi dà ancora / create invece di / quiz / create, che è l'intero URL
Sandip Subedi

Questo è un comportamento previsto. E dovresti abbracciarlo. Il gestore non dovrebbe preoccuparsi del percorso completo, ma solo della parte "locale" del percorso. Questa è la parte dopo il percorso su cui è stata montata. Ciò rende più semplice il riutilizzo della funzione gestore in altri contesti.
Stijn de Witt,

Risposte:


234

Dopo aver fatto un po 'di gioco, dovresti usare:

console.log(req.originalUrl)


3
Penso che abbia qualcosa a che fare con il posizionamento del middleware, ma hai ragione, non ha senso.
Menztrual,

1
È sicuramente il middleware. Questo accade anche con router aggiuntivi in ​​Express 4. Quando uno dei due è montato fuori da un determinato percorso, dentro di sé fa finta di essere fuori dalla radice. È bello per l'isolamento, ma è difficile quando non sai come ottenere il valore completo originale. Grazie per aver pubblicato questo!
juanpaco,

3
Chiunque arrivi qui su 4.0, req.url è progettato per essere mutabile dal middleware per scopi di reinstradamento e req.path potrebbe mancare punti di montaggio a seconda di dove viene chiamato. expressjs.com/en/api.html#req.originalUrl
Christian Davis,

3
Se non desideri includere la stringa di query:const path = req.originalUrl.replace(/\?.*$/, '');
Adam Reis,

1
Avvertenza: questa è una risposta fuorviante, basata sulla domanda del PO. Questo restituirà anche la stringa di query (ad esempio? A = b & c = 5) se era presente. Vedi expressjs.com/en/api.html#req.originalUrl
Ciabaros

60

In alcuni casi dovresti usare:

req.path

Questo ti dà il percorso, invece dell'URL completo richiesto. Ad esempio, se sei interessato solo alla pagina richiesta dall'utente e non a tutti i tipi di parametri, l'URL:

/myurl.htm?allkinds&ofparameters=true

req.path ti darà:

/myurl.html

1
Fai attenzione che se stai eseguendo dei controlli su questo URL per includere anche un controllo per una barra finale se è valida nella tua app. (vale a dire che il controllo /demodovrebbe anche potenzialmente verificare /demo/).
Vinay,

Se non si desidera includere la stringa di query: const path = req.originalUrl.replace (/\?.*$/, '');
Adam Reis,

req.pathè la scorciatoia di url.parse(req.url).pathnamee questa dovrebbe essere la risposta accettata
sertsedat il

1
@sertsedat Inesatto. req.pathti fornisce il percorso relativo a dove è montata la tua app. Se è montato alla radice di questo è corretto, ma per un percorso /my/path, all'interno di un'app montata su /my, req.urldarà /path.
Stijn de Witt,

21

Per completare, ecco un esempio ampliato dalla documentazione, che racchiude perfettamente tutto ciò che devi sapere sull'accesso ai percorsi / URL in tutti i casi con 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()
})

Basato su: https://expressjs.com/en/api.html#req.originalUrl

Conclusione: come afferma la risposta di c1moore sopra, utilizzare:

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 è / quando dovrebbe essere / account ??

La ragione di ciò è che Express sottrae il percorso su cui è montata la funzione del gestore, che è '/account'in questo caso.

Perché lo fanno?

Perché semplifica il riutilizzo della funzione del gestore. È possibile creare una funzione di gestore che fa cose diverse per req.path === '/'e req.path === '/goodbye'per esempio:

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

Quindi è possibile montarlo su più endpoint:

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

Dando:

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

9

Se vuoi davvero ottenere solo "path" senza querystring, puoi utilizzare la urllibreria per analizzare e ottenere solo parte del percorso di 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();
    }
});

questo è esattamente quello che voglio. Usalo con req.query.reflogin riuscito
Ryan Wu

Funziona bene con il codice universale poiché è conforme alle specifiche di posizione . Meno cose da ricordare e più semplice test unitario su client e server.
cchamberlain,

req.pathè solo un alias perurl.parse(req.url).pathname
mhodges

8

Per la versione 4.x ora è possibile utilizzare l' req.baseUrlaggiunta req.pathper ottenere il percorso completo. Ad esempio, l'OP ora farebbe qualcosa del tipo:

//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 sta lavorando per me

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

dopo l'esecuzione vedo quanto segue nella console e ottengo il risultato perfetto nel mio browser.

Express server listening on port 3000 in development mode
A call to route: /plants
Request type: get
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.