como obter o caminho da solicitação com o objeto express req

158

Estou usando express + node.js e tenho um objeto req, a solicitação no navegador é / account, mas quando eu registro req.path, recebo '/' --- 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 deveria ser / conta ??

chovy
fonte
2
TypeError: Cannot read property 'path' of undefined
chovy 21/09/12
req.route.path está correto e documentado aqui . Qual versão do express você está usando?
zemirco 21/09/12
Estou tendo o mesmo problema. req.routeestá indefinido. Estou usando express 3.4.4. O que pode fazer com que a rota seja indefinida?
davidpfahler
@vinayr req.route.path ainda me dá / criar em vez de / questionários / criar, que é toda a URL
Sandip Subedi
Esse é o comportamento pretendido. E você deve abraçar isso. Seu manipulador não deve se preocupar com o caminho completo, mas apenas com a parte 'local' do caminho. Essa é a parte após o caminho em que foi montada. Isso torna a função do manipulador mais fácil de reutilizar em outros contextos.
Stijn de Witt

Respostas:

234

Depois de me divertir um pouco, você deve usar:

console.log(req.originalUrl)

Menztrual
fonte
3
Eu acho que tem algo a ver com o posicionamento do middleware, mas você está correto, não faz sentido.
Menztrual 22/09/12
1
Definitivamente é o middleware. Isso acontece com roteadores adicionais no Express 4 também. Quando um deles é montado fora de um determinado caminho, dentro de si mesmo, ele finge que está fora da raiz. Isso é bom para o isolamento, mas complicado quando você não sabe como obter o valor total original. Obrigado por postar isso!
Juanpaco 23/04
3
Qualquer pessoa que esteja aqui na versão 4.0, req.url, foi projetada para ser mutável pelo middleware para fins de roteamento e o req.path pode estar perdendo pontos de montagem, dependendo de onde é chamado. expressjs.com/en/api.html#req.originalUrl
Christian Davis
3
Se você não deseja que a string de consulta seja incluída:const path = req.originalUrl.replace(/\?.*$/, '');
Adam Reis
1
Aviso: Esta é uma resposta enganosa, com base na pergunta do OP. Isso também retornará a string de consulta (por exemplo? A = b & c = 5), se estiver presente. Veja expressjs.com/en/api.html#req.originalUrl
Ciabaros
60

Em alguns casos, você deve usar:

req.path

Isso fornece o caminho, em vez do URL completo solicitado. Por exemplo, se você estiver interessado apenas em qual página o usuário solicitou e não em todos os tipos de parâmetros, o URL:

/myurl.htm?allkinds&ofparameters=true

O req.path fornecerá:

/myurl.html
DivZero
fonte
1
Tenha cuidado para que, se você estiver verificando esse URL, inclua também uma barra final, se for válida no seu aplicativo. (ou seja, a verificação /demotambém deve potencialmente verificar /demo/).
Vinay
Se você não deseja incluir a string de consulta: const path = req.originalUrl.replace (/\?.*$/, '');
Adam Reis
req.pathé a abreviação de url.parse(req.url).pathnamee esta deve ser a resposta aceita
sertsedat 10/03
1
@sertsedat Incorreto. req.pathfornece o caminho relativo para onde seu aplicativo está montado. Se ele estiver montado na raiz, isso estará correto, mas para um caminho /my/path, dentro de um aplicativo montado em /my, req.urlserá fornecido /path.
Stijn de Witt
21

Para complementar, aqui está um exemplo expandido da documentação, que inclui tudo o que você precisa saber sobre como acessar os caminhos / URLs em todos os casos com 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()
})

Com base em: https://expressjs.com/en/api.html#req.originalUrl

Conclusão: Como a resposta de c1moore afirma acima, use:

var fullPath = req.baseUrl + req.path;
Ciabaros
fonte
11

Deveria ser:

req.url

express 3.1.x

Jürgen Paul
fonte
req.url não é uma propriedade nativa do Express, é herdada do módulo http do nó: expressjs.com/en/api.html#req.originalUrl
Megagator
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 deveria ser / conta ??

A razão para isso é que o Express subtrai o caminho em que sua função de manipulador está montada, o que é '/account'nesse caso.

Porque é que eles fazem isto?

Porque facilita reutilizar a função de manipulador. Você pode fazer uma função do manipulador que faz coisas diferentes para req.path === '/'e req.path === '/goodbye'por exemplo:

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

Em seguida, você pode montá-lo em vários pontos de extremidade:

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

Dando:

/world           ==>  Hello there!
/world/goodbye   ==>  Farewell!
/aliens          ==>  Hello there!
/aliens/goodbye  ==>  Farewell!
Stijn de Witt
fonte
9

Se você realmente deseja obter apenas o "caminho" sem a string de consulta, pode usar a urlbiblioteca para analisar e obter apenas parte do caminho do 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();
    }
});
Murat Çorlu
fonte
é exatamente isso que eu quero. Use-o com req.query.refse login bem-sucedido
Ryan Wu
Isso funciona muito bem com o código universal, pois está em conformidade com as especificações do local . Menos coisas para lembrar e mais fácil para testar a unidade no cliente e no servidor.
Cchamberlain 11/10
req.pathé apenas um apelido paraurl.parse(req.url).pathname
mhodges 20/04
8

Para a versão 4.x, agora você pode usar o req.baseUrlalém req.pathpara obter o caminho completo. Por exemplo, o OP agora faria algo como:

//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();
  }
});
c1moore
fonte
5

req.route.path está funcionando para mim

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

após a execução, vejo o seguinte no console e obtenho um resultado perfeito no meu navegador.

Express server listening on port 3000 in development mode
A call to route: /plants
Request type: get
Bahman.A
fonte