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

Posted

技术标签:

【中文标题】如何使用 express req 对象获取请求路径【英文标题】:how to get request path with express req object 【发布时间】:2012-09-13 14:30:41 【问题描述】:

我正在使用 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();
    
  );

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

【问题讨论】:

TypeError: Cannot read property 'path' of undefined req.route.path 是正确的并记录在here。您使用的是哪个版本的 express? 我遇到了同样的问题。 req.route 未定义。我使用快递 3.4.4。什么会导致路由未定义? @vinayr req.route.path 仍然给我 /create 而不是 /quizzes/create,这是整个 URL 这是预期行为。你应该接受它。您的处理程序不应该关心完整路径,而只关心路径的“本地”部分。这是安装路径之后的部分。这使得处理函数更容易在其他上下文中重用。 【参考方案1】:

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

console.log(req.originalUrl)

【讨论】:

我认为这与中间件的定位有关,但你是对的,这没有意义。 绝对是中间件。 Express 4 中的其他路由器也会发生这种情况。当任何一个安装在给定路径之外时,它在自身内部就会假装它不在根目录下。这对于隔离来说很好,但是当您不知道如何获得原始完整值时会很棘手。感谢您发布此信息! 任何人在 4.0 上都能看到,req.url 被设计为可以被中间件更改以用于重新路由,并且 req.path 可能会丢失安装点,具体取决于它被调用的位置。 expressjs.com/en/api.html#req.originalUrl 如果您不想包含查询字符串:const path = req.originalUrl.replace(/\?.*$/, ''); 警告:这是基于 OP 问题的误导性答案。如果存在,这也将返回查询字符串(例如 ?a=b&c=5)。见expressjs.com/en/api.html#req.originalUrl【参考方案2】:

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

req.path

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

/myurl.htm?allkinds&ofparameters=true

req.path 会给你:

/myurl.html

【讨论】:

请注意,如果您对这个 URL 进行检查,还要检查尾部斜杠是否在您的应用中有效。 (即检查/demo 也应该检查/demo/)。 如果不希望包含查询字符串: const path = req.originalUrl.replace(/\?.*$/, ''); req.pathurl.parse(req.url).pathname 的简写,这应该是公认的答案 @sertsedat 不正确。 req.path 为您提供安装应用程序的相对路径。如果它安装在根目录下是正确的,但对于路径/my/path,在安装在/my 的应用程序中,req.url 将给出/path【参考方案3】:

作为补充,这里是从文档扩展而来的示例,它很好地包含了您在所有情况下使用 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;

【讨论】:

【参考方案4】:

8 年后更新:

req.path 是我在这里提到的already doing exactly same thing。我不记得这个答案是如何解决问题并被接受为正确答案的,但目前这不是一个有效的答案。请忽略这个答案。感谢@mhodges 提到这一点。

原答案:

如果你真的想只得到没有查询字符串的“路径”,你可以使用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.query.ref 一起使用 这适用于通用代码,因为它符合 Location 规范。需要记住的事情更少,并且更容易跨客户端和服务器进行单元测试。 req.path 只是 url.parse(req.url).pathname 的别名 @mhodges 哇,这看起来完全正确。这是一个已有 8 年历史的答案,我不知道我们认为该答案如何解决了这个问题。谢谢提及。我会更新答案或者干脆删除它。【参考方案5】:

应该是:

req.url

表达 3.1.x

【讨论】:

req.url 不是原生 Express 属性,它继承自 Node 的 http 模块:expressjs.com/en/api.html#req.originalUrl【参考方案6】:

对于 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();
  
);

【讨论】:

【参考方案7】:
//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 是 / 什么时候应该是 /account ??

原因是 Express 减去了你的处理函数的挂载路径,在本例中为 '/account'

他们为什么这样做?

因为它更容易重用处理函数。您可以创建一个处理函数,对 req.path === '/'req.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!

【讨论】:

【参考方案8】:

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

【讨论】:

【参考方案9】:

1。直接从主文件(app.js / index.js)调用:

app.get('/admin/:foo/:bar/:baz', async (req, res) => 
    console.log(req.originalUrl);
    console.log(req.url);
    console.log(req.path);
    console.log(req.route.path);
    console.log(req.baseUrl);
    console.log(req.hostname);
    console.log(req.headers.host) // OR req.header('host'));
    console.log(req.protocol);

    res.sendStatus(200);
);

API 调用:

http://localhost:3000/admin/a/b/c

输出

/admin/a/b/c (originalUrl)/admin/a/b/c (url)/admin/a/b/c (path)/admin/:foo/:bar/:baz (route.path) (baseUrl)localhost(主机名)localhost:3000(headers.host(主机名和端口号))http(协议)


2。从模块调用:

app.js

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

...

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

users.js

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

...

router.get('/admin/:foo/:bar/:baz', async (req, res) => 
    console.log(req.originalUrl);
    console.log(req.url);
    console.log(req.path);
    console.log(req.route.path);
    console.log(req.baseUrl);
    console.log(req.hostname);
    console.log(req.headers.host) // OR req.header('host'));
    console.log(req.protocol);

    res.sendStatus(200);
);

API 调用:

http://localhost:3000/admin/a/b/c

输出

/api/users/admin/a/b/c (originalUrl)/admin/a/b/c (url)/admin/a/b/c (path)/admin/:foo/:bar/:baz (route.path)/api/users (baseUrl)localhost(主机名)localhost:3000(headers.host(主机名和端口号))http(协议)

【讨论】:

req.routeundefined 你能分享你的代码 sn-p(例如 JSFiddle 等)吗?

以上是关于如何使用 express req 对象获取请求路径的主要内容,如果未能解决你的问题,请参考以下文章

node和express

request和response对象的具体介绍

nodejsrequest 和 response 对象

在Express中get,post获取表单请求数据

获取 Express 中的请求数

expressjs req.url 路径如何成为另一个url?