我使用express + node.js,我有一个req对象,浏览器中的请求是/帐户,但当我日志req. js。我得到'/' -而不是'/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();
    }
  });

要求的事情。路径是/当它应该是/account ??


在我自己玩了一会之后,你应该使用:

console.log (req.originalUrl)


它应该是:

req.url

快递里


在某些情况下,你应该使用:

req.path

这将为您提供路径,而不是完整的请求URL。例如,如果你只对用户请求的页面感兴趣,而不关心url的所有参数:

/myurl.htm?allkinds&ofparameters=true

要求的事情。Path会给你:

/myurl.html

8年后更新:

要求的事情。path已经做了和我这里提到的完全一样的事情。我不记得这个答案是如何解决问题并被接受为正确答案的,但目前它不是一个有效的答案。请忽略这个回答。谢谢@mhodges提到这一点。

最初的回答:

如果你真的想只得到“路径”而没有querystring,你可以使用url库来解析并只得到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();
    }
});

Req.route.path对我有用

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

执行后,我看到以下在控制台和我得到完美的结果 在我的浏览器里。

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

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

要求的事情。路径是/当它应该是/account ??

这样做的原因是Express减去你的处理程序函数挂载的路径,在本例中是'/account'。

他们为什么要这样做?

因为这样可以更容易地重用处理程序函数。您可以为req创建一个处理程序函数来做不同的事情。Path === '/'和req. Path。Path === '/goodbye'例如:

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

然后你可以将它挂载到多个端点:

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

给:

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

对于版本4。X你现在可以使用请求。除了req之外的baseUrl。获取完整路径。例如,OP现在会做这样的事情:

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

下面是一个从文档中扩展的例子,它很好地包装了所有你需要知道的关于在所有情况下使用express访问路径/ url的信息:

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

基于:https://expressjs.com/en/api.html#req.originalUrl

结论:如c1moore’s answer所述,使用:

var fullPath = req.baseUrl + req.path;

这可以产生不同的结果时,直接调用基本模块,即主文件(如index.js或app.js) vs从模块内部调用通过app.use()中间件,即路由文件(如routes/users.js)。

电话:火

http://localhost:8000/api/users/profile/123/summary?view=grid&leng=en

我们将把我们的输出与上面的API调用进行比较


1)首先,我们将看到来自模块内部的结果:

我们将把我们的用户模块放在routes目录中,只有一个路由

路线/ users.js

const router = (require('express')).Router();

router.get('/profile/:id/:details', (req, res) => {

    console.log(req.protocol);        // http or https
    console.log(req.hostname);        // only hostname (abc.com, localhost, etc)
    console.log(req.headers.host);    // hostname with port number (if any)
    console.log(req.header('host'));  // <same as above>
    console.log(req.route.path);      // exact defined route
    console.log(req.baseUrl);         // base path or group prefix
    console.log(req.path);            // relative path except path
    console.log(req.url);             // relative path with query|search params
    console.log(req.originalUrl);     // baseURL + url

    // Full URL
    console.log(`${req.protocol}://${req.header('host')}${req.originalUrl}`);

    res.sendStatus(200);

});

module.exports = router;

index.js

const app = (require('express'))();

const users = require('./routes/users');
app.use('/api/users', users);

const server = require('http').createServer(app);
server.listen(8000, () => console.log('server listening'));

输出

http ....................................................................................... [protocol] localhost .............................................................................. [hostname] localhost:8000 ..................................................................... [headers.host] localhost:8000 ..................................................................... [header('host')] /profile/:id/:details ........................................................ [route.path] /api/users ............................................................................. [baseUrl] /profile/123/summary .......................................................... [path] /profile/123/summary?view=grid&leng=en ........................ [url] /api/users/profile/123/summary?view=grid&leng=en ..... [originalUrl]

完整的URL: http://localhost:8000/api/users/profile/123/summary?view=grid&leng=en


2)现在,直接从主模块:

我们将在起始文件(即app.js或index.js)中定义我们的路由

index.js

const app = (require('express'))();

app.get('/api/users/profile/:id/:details', (req, res) => {

    console.log(req.protocol);        // http or https
    console.log(req.hostname);        // only hostname (abc.com, localhost, etc)
    console.log(req.headers.host);    // hostname with port number (if any)
    console.log(req.header('host'));  // <same as above>
    console.log(req.route.path);      // exact defined route
    console.log(req.baseUrl);         // base path or group prefix
    console.log(req.path);            // relative path except path
    console.log(req.url);             // relative path with query|search params
    console.log(req.originalUrl);     // baseURL + url

    // Full URL
    console.log(`${req.protocol}://${req.header('host')}${req.originalUrl}`);

    res.sendStatus(200);

});

const server = require('http').createServer(app);
server.listen(8000, () => console.log('server listening'));

输出

http ........................................................................ [protocol] localhost ............................................................... [hostname] localhost:8000 ...................................................... [headers.host] localhost:8000 ...................................................... [header('host')] /profile/:id/:details ......................................... [route.path] .............................................................................. [baseUrl] /profile/123/summary ........................................... [path] /profile/123/summary?view=grid&leng=en ......... [url] /profile/123/summary?view=grid&leng=en ......... [originalUrl]

完整的URL: http://localhost:8000/api/users/profile/123/summary?view=grid&leng=en

在上面的输出中,我们可以清楚地看到,唯一的区别是baseUrl在这里是空字符串。因此,originalUrl也会改变&看起来与url相同


对于那些从request .route.path中获得未定义的,这是正确的。

在路由处理器内部,有一个路由。 在中间件处理程序内部,没有路由。