如何使用express req对象获取请求路径

cho*_*ovy 133 javascript node.js express

我正在使用express + node.js并且我有一个req对象,浏览器中的请求是/ account但是当我记录req.path时我得到'/'---不是'/ 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();
    }
  });
Run Code Online (Sandbox Code Playgroud)

req.path是/什么时候应该是/ account?

Men*_*ual 206

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

console.log(req.originalUrl)

  • 警告:这是基于 OP 问题的误导性答案。如果它存在,这也将返回查询字符串(例如?a=b&c=5)。见 http://expressjs.com/en/api.html#req.originalUrl (4认同)
  • 仍然不清楚为什么req.path不能正常工作. (3认同)
  • 我认为它与中间件的定位有关,但你是对的,没有意义. (3认同)
  • 任何在4.0上使用此工具的人,req.url都被设计为可由中间件可变以用于重新路由,并且req.path可能会丢失挂载点,具体取决于调用的位置。http://expressjs.com/zh_CN/api.html#req.originalUrl (2认同)
  • 如果您不希望包含查询字符串:`const path = req.originalUrl.replace(/\?.*$/,'');` (2认同)

Div*_*ero 49

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

req.path
Run Code Online (Sandbox Code Playgroud)

这为您提供了路径,而不是完整请求的URL.例如,如果您只对用户请求的页面感兴趣,而不是所有类型的参数url:

/myurl.htm?allkinds&ofparameters=true
Run Code Online (Sandbox Code Playgroud)

req.path会给你:

/myurl.html
Run Code Online (Sandbox Code Playgroud)

  • @sertsedat 不正确。`req.path` 为您提供应用程序安装位置的相对路径。如果它安装在根目录,则这是正确的,但对于路径“/my/path”,在安装在“/my”的应用程序中,“req.url”将给出“/path”。 (2认同)

Tal*_*iqi 19

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

API调用:
http://localhost:8000/api/users/profile/123/summary?view=grid&leng=en
Run Code Online (Sandbox Code Playgroud)

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


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

  1. 我们将把我们的用户模块放在路由目录中,其中有一个路由,即/profile/:id/:details

    路线/user.js文件

    http://localhost:8000/api/users/profile/123/summary?view=grid&leng=en
    
    Run Code Online (Sandbox Code Playgroud)
  2. 现在我们将在应用程序的主模块中导入此用户模块,并使用中间件添加/api/users为用户模块的基本路径app.use()

    索引.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 without port
        console.log(req.headers.host);    // hostname with port number (if any); same result with req.header('host')
        console.log(req.route.path);      // exact defined route
        console.log(req.baseUrl);         // base path or group prefix
        console.log(req.path);            // relative path except query params
        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;
    
    Run Code Online (Sandbox Code Playgroud)

输出

[req.protocol] ........ http
[req.hostname] ........ localhost
[req.headers.host] ..... localhost:8000
[req.route。路径] ................. /profile/:id/:details
[req.baseUrl] ................. /api/users
[req.path] ........................ ..... /profile/123/summary
[req.url] ........................ /profile/123/summary?view=grid&leng=en
[req.originalUrl] ......................../api/users/profile/123/summary?view=grid&leng=en

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


现在,如果我们直接在主模块中添加路由,我们将看到结果:

  1. 我们将在主模块(即 app.js 或 index.js)中定义路由,并将基本路径/app/users与路由路径连接起来,而不是使用中间件。所以路线将变成/api/users/profile/:id/:details

    索引.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'));
    
    Run Code Online (Sandbox Code Playgroud)

输出

[req.protocol] ........ http
[req.hostname] ........ localhost
[req.headers.host] ..... localhost:8000
[req.route。路径] ................. /api/users/profile/:id/:details
[req.baseUrl] .................
[req.path] ........................ ..... /api/users/profile/123/summary
[req.url] ........................ /api/users/profile/123/summary?view=grid&leng=en
[req.originalUrl] ......................../api/users/profile/123/summary?view=grid&leng=en

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

我们可以在上面的输出中清楚地看到,唯一的区别是baseUrl这里是空字符串。所以,originalUrl也发生了变化并且看起来与url

  • “req.route”是“未定义” (3认同)

Jür*_*aul 11

它应该是:

req.url

表达3.1.x


Mur*_*rlu 9

如果你想真正只获得没有查询字符串的"路径",你可以使用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();
    }
});
Run Code Online (Sandbox Code Playgroud)


Sti*_*itt 8

//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();
  }
});
Run Code Online (Sandbox Code Playgroud)

req.path是/什么时候应该是/ account?

这样做的原因是Express减去了处理函数的路径,'/account'在这种情况下.

他们为什么这样做呢?

因为它使重用处理函数变得更容易.你可以做一个处理函数,它为不同的事情req.path === '/'req.path === '/goodbye'例如:

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

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

app.use('/world', sendGreeting)
app.use('/aliens', sendGreeting)
Run Code Online (Sandbox Code Playgroud)

赠送:

/world           ==>  Hello there!
/world/goodbye   ==>  Farewell!
/aliens          ==>  Hello there!
/aliens/goodbye  ==>  Farewell!
Run Code Online (Sandbox Code Playgroud)


c1m*_*ore 7

对于4.x版,您现在可以使用req.baseUrlreq.path来获取完整路径。例如,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();
  }
});
Run Code Online (Sandbox Code Playgroud)


Cia*_*ros 6

作为补充,这是从文档扩展而来的示例,该示例很好地包装了您需要在所有情况下使用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()
})
Run Code Online (Sandbox Code Playgroud)

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

结论:如上面c1moore的回答所述,请使用:

var fullPath = req.baseUrl + req.path;
Run Code Online (Sandbox Code Playgroud)


Bah*_*n.A 5

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);
        });
    });
};
Run Code Online (Sandbox Code Playgroud)

执行后,我在控制台中看到以下内容,并且在浏览器中得到了完美的结果。

Express server listening on port 3000 in development mode
A call to route: /plants
Request type: get
Run Code Online (Sandbox Code Playgroud)