假设我的示例网址是
我说我有以下路线
app.get('/one/two', function (req, res) {
var url = req.url;
}
url
的值为/one/two
。
如何在Express中获得完整网址?
例如,在上面的情况中,我希望收到http://example.com/one/two
。
答案 0 :(得分:629)
该协议以req.protocol
的形式提供。 docs here
http
,除非您看到req.get('X-Forwarded-Protocol')
已设置并且值为https
,在这种情况下您知道这是您的协议主持人来自req.get('host')
,正如Gopal指出
希望您的网址中不需要非标准端口,但是如果您确实需要知道它,那么您的应用程序状态就是这样,因为它是您传递给app.listen
的任何内容服务器启动时间。但是,在非标准端口上进行本地开发的情况下,Chrome似乎在主机标头中包含端口,因此req.get('host')
会返回localhost:3000
。因此,至少对于标准端口上的生产站点并直接浏览到您的快速应用程序(没有反向代理)的情况,host
标题似乎对URL中的端口做了正确的事情。
路径来自req.originalUrl
(感谢@pgrassant)。请注意,此DOES包含查询字符串。 docs here on req.url and req.originalUrl。根据您打算对网址执行的操作,与originalUrl
相比,req.url
可能是也可能不是正确的值。
将所有这些组合在一起以重建绝对URL。
var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
答案 1 :(得分:109)
您可以改为使用the node.js API for URLs并从快递传递URL.format()
信息,而不是自己将事物连接在一起。
示例:
var url = require('url');
function fullUrl(req) {
return url.format({
protocol: req.protocol,
host: req.get('host'),
pathname: req.originalUrl
});
}
答案 2 :(得分:32)
我发现获得请求的网址有点像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;
答案 3 :(得分:17)
使用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);
答案 4 :(得分:15)
这是添加一个可以在req对象上调用以获取url
的函数的好方法 app.use(function(req, res, next) {
req.getUrl = function() {
return req.protocol + "://" + req.get('host') + req.originalUrl;
}
return next();
});
现在你有一个功能,你可以根据需要随叫随到。
答案 5 :(得分:9)
使req.host/req.hostname有效必须在Express behind proxies时有两个条件:
app.set('trust proxy', 'loopback');
X-Forwarded-Host
标头必须由您自己在网络服务器中指定。例如。 apache,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>
答案 6 :(得分:8)
使用此,
var url = req.headers.host + '/' + req.url;
答案 7 :(得分:6)
我的代码看起来像这样,
params['host_url'] = req.protocol + '://' + req.headers.host + req.url;
答案 8 :(得分:6)
我建议使用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 */ });
所以我们的网址格式为:
www.example.com/foo/bar/:barparam
因此,我们需要bar控制器获取处理程序中的req.originalUrl。
答案 9 :(得分:6)
您需要使用req.headers.host + req.url
构建它。当然,如果你在不同的港口托管,你就会明白这一点; - )
答案 10 :(得分:6)
var full_address = req.protocol + "://" + req.headers.host + req.originalUrl;
或
var full_address = req.protocol + "://" + req.headers.host + req.baseUrl;
答案 11 :(得分:5)
下面的代码对我来说足够了!
const baseUrl = `${request.protocol}://${request.headers.host}`;
// http://127.0.0.1:3333
答案 12 :(得分:4)
我使用节点包'url'(npm install url)
当您致电
时,它的作用是什么url.parse(req.url, true, true)
它将为您提供检索全部或部分网址的可能性。更多信息: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
}
答案 13 :(得分:1)
我实际上发现通过使用下面的代码,您可以获得您的网址。然后继续切片并决定下一步。
app.use(function(req, res, next) {
console.log(req.originalUrl);
res.send(req.originalUrl);
});
答案 14 :(得分:1)
async function (request, response, next) {
const url = request.rawHeaders[9] + request.originalUrl;
//or
const url = request.headers.host + request.originalUrl;
}
答案 15 :(得分:1)
2021 年
上述答案工作正常但不是文档首选,因为 url.parse
现在是 legacy
所以我建议你使用 new URL()
函数如果你想获得更多的控制 {{ 1}}。
您可以从以下代码中获取 url
。
Full URL
示例网址:http://localhost:5000/a/b/c?d=true&e=true#f=false
固定属性(您将在所有路由中获得相同的结果)
`${req.protocol}://${req.get('host')}${req.originalUrl}`
非固定属性(每条路线都会改变,因为它是由快递自己控制的)
路线: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
文档:http://expressjs.com/en/api.html#req.baseUrl
在 req.baseUrl: /a
req.url: /b/c?d=true&e=true
req.path: /b/c
函数中,您将在每条路线中获得相同的结果,因此属性始终固定。
属性
URL
您将得到如下结果。我根据图像更改了属性的顺序,以便它可以匹配图像流。
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
,但您会在客户端浏览器中得到它。 >
答案 16 :(得分:0)
谢谢大家提供此信息。这真令人讨厌。
将其添加到您的代码中,您无需再考虑它:
var app = express();
app.all("*", function (req, res, next) { // runs on ALL requests
req.fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl
next()
})
您还可以在那里执行或设置其他操作,例如登录到控制台。
答案 17 :(得分:0)
您可以在这样的路线中使用此功能
app.get('/one/two', function (req, res) {
var url = getFullUrl(req);
}
var getFullUrl = function(req) {
return `${req.protocol}://${req.headers.host}${req.orignalUrl}`
}
req.protocol
将为您提供http或https,
req.headers.host
将为您提供完整的主机名,例如www.google.com,
req.orignalUrl
将提供其余的pathName
(在您的情况下为/one/two
)