190
votes

I'm using express + node.js and I have a req object, the request in the browser is /account but when I log req.path I get '/' --- 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 is / when it should be /account ??

8
TypeError: Cannot read property 'path' of undefined - chovy
req.route.path is correct and documented here. Which version of express are you using? - zemirco
I'm having the same issue. req.route is undefined. Im using express 3.4.4. What can cause route to be undefined? - davidpfahler
@vinayr req.route.path still gives me /create instead of /quizzes/create, which is the whole URL - Sandip Subedi
This is intended behavior. And you should embrace it. Your handler should not care about the full path, but only about the 'local' part of the path. That's the part after the path it was mounted on. This makes the handler function more easy to reuse in other contexts. - Stijn de Witt

8 Answers

285
votes

After having a bit of a play myself, you should use:

console.log(req.originalUrl)

69
votes

In some cases you should use:

req.path

This gives you the path, instead of the complete requested URL. For example, if you are only interested in which page the user requested and not all kinds of parameters the url:

/myurl.htm?allkinds&ofparameters=true

req.path will give you:

/myurl.html
54
votes

To supplement, here is an example expanded from the documentation, which nicely wraps all you need to know about accessing the paths/URLs in all cases with 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()
})

Based on: https://expressjs.com/en/api.html#req.originalUrl

Conclusion: As c1moore's answer states, use:

var fullPath = req.baseUrl + req.path;
12
votes

It should be:

req.url

express 3.1.x

10
votes
//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 is / when it should be /account ??

The reason for this is that Express subtracts the path your handler function is mounted on, which is '/account' in this case.

Why do they do this?

Because it makes it easier to reuse the handler function. You can make a handler function that does different things for req.path === '/' and req.path === '/goodbye' for example:

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

Then you can mount it to multiple endpoints:

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

Giving:

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

If you want to really get only "path" without querystring, you can use url library to parse and get only path part of 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();
    }
});
9
votes

For version 4.x you can now use the req.baseUrl in addition to req.path to get the full path. For example, the OP would now do something like:

//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
votes

req.route.path is working for 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);
        });
    });
};

after executing I see the following in the console and I get perfect result in my browser.

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