如何使用 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.path
是url.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.baseUrl
和 req.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.route
是undefined
你能分享你的代码 sn-p(例如 JSFiddle 等)吗?以上是关于如何使用 express req 对象获取请求路径的主要内容,如果未能解决你的问题,请参考以下文章