假设我的示例网址是
http://example.com/one/two
我说我有以下路线
app.get('/one/two', function (req, res) {
var url = req.url;
}
url
的值为 /one/two
。
如何在 Express 中获取完整 URL?例如,在上述情况下,我想收到 http://example.com/one/two
。
该协议以 req.protocol 的形式提供。 docs here 在 express 3.0 之前,您可以假设协议是 http 除非您看到 req.get('X-Forwarded-Protocol') 已设置并具有值 https,在这种情况下您知道这是您的协议主机来自req.get('host') 正如 Gopal 所指出的那样,希望您的 URL 中不需要非标准端口,但如果您确实需要知道它,您将在您的应用程序状态中拥有它,因为它是您传递给的任何内容app.listen 在服务器启动时。但是,在非标准端口上进行本地开发的情况下,Chrome 似乎将端口包含在主机标头中,因此 req.get('host') 会返回 localhost:3000,例如。因此,至少对于标准端口上的生产站点并直接浏览到您的快速应用程序(没有反向代理)的情况,主机标头似乎对 URL 中的端口做了正确的事情。路径来自 req.originalUrl(感谢@pgrassant)。请注意,这确实包括查询字符串。 req.url 和 req.originalUrl 上的文档。根据您打算对 URL 执行的操作,与 req.url 相比,originalUrl 可能是正确的值,也可能不是正确的值。
将这些组合在一起以重建绝对 URL。
var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
您可以使用 the node.js API for URLs 并传递 URL.format()
来自 express 的信息,而不是自己将这些东西连接在一起。
例子:
var url = require('url');
function fullUrl(req) {
return url.format({
protocol: req.protocol,
host: req.get('host'),
pathname: req.originalUrl
});
}
req.get('host')
只返回 hostname 部分,而不是端口。不知道为什么,但现在我从设置中收集端口号,并使用 hostname
字段,而不是 host
。
pathname
,而是 path
。其中包括搜索/查询字符串
const url = new URL(req.protocol + '://' + req.get('host') + req.originalUrl)
url.format
现在已弃用。
我发现获取请求的 url 有点像 PITA。我不敢相信没有更简单的表达方式。应该只是 req.requested_url
但我是这样设置的:
var port = req.app.settings.port || cfg.port;
res.locals.requested_url = req.protocol + '://' + req.host + ( port == 80 || port == 443 ? '' : ':'+port ) + req.path;
req.port
存在吗?它不在 Express 文档中吗?
req.app.settings.port
获得它
这是添加函数的好方法,您可以在 req 对象上调用以获取 url
app.use(function(req, res, next) {
req.getUrl = function() {
return req.protocol + "://" + req.get('host') + req.originalUrl;
}
return next();
});
现在你有了一个可以按需调用的函数。
2021年
上述答案工作正常,但文档不喜欢,因为 url.parse
现在是 legacy
,所以如果您想获得对 url
的更多控制,我建议您使用 new URL()
函数。
高速公路
您可以从以下代码中获取 Full URL
。
`${req.protocol}://${req.get('host')}${req.originalUrl}`
示例 URL:http://localhost:5000/a/b/c?d=true&e=true#f=false
固定属性(您将在所有路线中获得相同的结果)
req.protocol: http
req.hostname: localhost
req.get('Host'): localhost:5000
req.originalUrl: /a/b/c?d=true&e=true
req.query: { d: 'true', e: 'true' }
不固定属性(每条路线都会改变,因为它由快递本身控制)
路线:/
req.baseUrl: <blank>
req.url: /a/b/c?d=true&e=true
req.path: /a/b/c
路线 /a
req.baseUrl: /a
req.url: /b/c?d=true&e=true
req.path: /b/c
文档:http://expressjs.com/en/api.html#req.baseUrl
URL封装方式
在 URL
函数中,您将在每条路线中获得相同的结果,因此属性始终是固定的。
特性
https://i.stack.imgur.com/QKa0Q.png
const url = new URL(`${req.protocol}://${req.get('host')}${req.originalUrl}`);
console.log(url)
您将得到如下所示的结果。我根据图像更改了属性的顺序,以便它可以匹配图像流。
URL {
href: 'http://localhost:5000/a/b/c?d=true&e=true',
protocol: 'http:',
username: '',
password: '',
hostname: 'localhost',
port: '5000',
host: 'localhost:5000',
origin: 'http://localhost:5000',
pathname: '/a/b/c',
search: '?d=true&e=true',
searchParams: URLSearchParams { 'd' => 'true', 'e' => 'true' },
hash: ''
}
注意:Hash
不能发送到服务器,因为它在服务器中被视为 Fragment
,但您会在客户端即浏览器中得到它。
文档:https://nodejs.org/api/url.html#url_new_url_input_base
req.get("host")
将包含端口,但除了不推荐使用“主机”之外,情况并非如此。
get()
用于获取请求的标头,在请求中,您有 host
标头,因此它只需调用请求标头并获取端口,使用起来非常安全,这里没有任何内容被取消
使用 url.format:
var url = require('url');
这支持所有协议并包括端口号。如果您的 originalUrl 中没有查询字符串,您可以使用这个更简洁的解决方案:
var requrl = url.format({
protocol: req.protocol,
host: req.get('host'),
pathname: req.originalUrl,
});
如果您有查询字符串:
var urlobj = url.parse(req.originalUrl);
urlobj.protocol = req.protocol;
urlobj.host = req.get('host');
var requrl = url.format(urlobj);
使 req.host/req.hostname 在 Express behind proxies 时生效必须有两个条件:
app.set('信任代理', 'loopback'); app.js 中的 X-Forwarded-Host 标头必须由您在网络服务器中指定。例如。阿帕奇, nginx
nginx:
server {
listen myhost:80;
server_name myhost;
location / {
root /path/to/myapp/public;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://myapp:8080;
}
}
阿帕奇:
<VirtualHost myhost:80>
ServerName myhost
DocumentRoot /path/to/myapp/public
ProxyPass / http://myapp:8080/
ProxyPassReverse / http://myapp:8080/
</VirtualHost>
req.get('host')
得到 127.0.0.1
用这个,
var url = req.headers.host + '/' + req.url;
只是下面的代码对我来说就足够了!
const baseUrl = `${request.protocol}://${request.headers.host}`;
// http://127.0.0.1:3333
我建议使用 originalUrl 而不是 URL:
var url = req.protocol + '://' + req.get('host') + req.originalUrl;
在此处查看 originalUrl 的说明:http://expressjs.com/api.html#req.originalUrl
在我们的系统中,我们做了这样的事情,所以 originalUrl 对我们很重要:
foo = express();
express().use('/foo', foo);
foo.use(require('/foo/blah_controller'));
blah_controller 看起来像这样:
controller = express();
module.exports = controller;
controller.get('/bar/:barparam', function(req, res) { /* handler code */ });
所以我们的 URL 具有以下格式:
www.example.com/foo/bar/:barparam
因此,我们需要在 bar 控制器 get 处理程序中使用 req.originalUrl。
var full_address = req.protocol + "://" + req.headers.host + req.originalUrl;
或者
var full_address = req.protocol + "://" + req.headers.host + req.baseUrl;
您需要使用 req.headers.host + req.url
构建它。当然,如果您在不同的端口托管,那么您就会明白;-)
req.protocol
我使用节点包'url'(npm install url)
它的作用是当你打电话时
url.parse(req.url, true, true)
它将使您能够检索全部或部分 url。更多信息:https://github.com/defunctzombie/node-url
我以以下方式使用它来获取 http://www.example.com/ 中 / 之后的任何内容以用作变量并提取特定的配置文件(有点像 facebook:http://www.facebook.com/username)
var url = require('url');
var urlParts = url.parse(req.url, true, true);
var pathname = urlParts.pathname;
var username = pathname.slice(1);
尽管要使其正常工作,但您必须在 server.js 文件中以这种方式创建路由:
self.routes['/:username'] = require('./routes/users');
并以这种方式设置您的路线文件:
router.get('/:username', function(req, res) {
//here comes the url parsing code
}
我的代码看起来像这样,
params['host_url'] = req.protocol + '://' + req.headers.host + req.url;
您可以像这样在路线中使用此功能
app.get('/one/two', function (req, res) {
const url = getFullUrl(req);
}
/**
* Gets the self full URL from the request
*
* @param {object} req Request
* @returns {string} URL
*/
const getFullUrl = (req) => `${req.protocol}://${req.headers.host}${req.originalUrl}`;
req.protocol
将为您提供 http 或 https,req.headers.host
将为您提供完整的主机名,例如 www.google.com,req.originalUrl
将提供其余的pathName
(在您的情况下为 /one/two
)
您可以从 express 的 req 中获取完整的 url。
function fetchPages(req, res, next) {
let fullUrl = req.headers.host + req.originalUrl;
console.log("full url ==> ",fullUrl);
}
谢谢大家提供这些信息。这是令人难以置信的烦人。
将此添加到您的代码中,您将永远不必再考虑它:
var app = express();
app.all("*", function (req, res, next) { // runs on ALL requests
req.fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl
next()
})
您也可以在那里执行或设置其他操作,例如登录到控制台。
您可以组合 req.protocol
、req.hostname
和 req.originalUrl
。注意 req.hostname
而不是 req.host
或 req.get("host")
,它们有效但更难阅读。
const completeUrl = `${req.protocol}://${req.hostname}${req.originalUrl}`;
async function (request, response, next) {
const url = request.rawHeaders[9] + request.originalUrl;
//or
const url = request.headers.host + request.originalUrl;
}
我试图只记录 req 的所有数据
然后我发现记录 rawHeaders 并找到 url 中可用的所有数据
我试过这个
app.post("/news-letter", (req,res) => {
console.log(req.body);
res.redirect(req.rawHeaders[33]);
})
通常我依赖这2个,取决于服务器和代理是否存在:
req.socket.remoteAddress
req.headers.referer
const fullUrl = `${protocol}://${host}:${port}${url}`
const responseString = `Full URL is: ${fullUrl}`;
res.send(responseString);
})
只需将它放在 .env
中,其中 .gitignore 忽略 .env 文件,因此对于每个服务器环境,您将拥有不同的 .env,其中包含该服务器的主机字符串
.env 代码
HOSTNAME=example.com
您想要热名称的文件。
const dotenv = require("dotenv");
dotenv.config();
console.log('hostname: '+process.env.HOSTNAME)
输出:
hostname: example.com
req.get('Host')
而不是req.host
提供主机和端口部分。host
参数可以被欺骗。如果以这种方式使用res.host
,则可能存在“主机头攻击”。在 Django 框架中,它们有一个“允许的主机”变量,用于防止此类攻击。我使用了一个配置变量,即我的root_url
,它可以添加到req.url
以完成。关于攻击:skeletonscribe.net/2013/05/…req.originalUrl
,只需执行req.originalUrl.split("?").shift()
。来源:stackoverflow.com/a/32118818/2037431