如何在Express中获取完整的URL?

时间:2012-04-16 23:57:07

标签: node.js url express

假设我的示例网址是

  

http://example.com/one/two

我说我有以下路线

app.get('/one/two', function (req, res) {
    var url = req.url;
}

url的值为/one/two

如何在Express中获得完整网址? 例如,在上面的情况中,我希望收到http://example.com/one/two

18 个答案:

答案 0 :(得分:629)

  1. 该协议以req.protocol的形式提供。 docs here

    1. 在Express 3.0之前,您可以假设协议为http,除非您看到req.get('X-Forwarded-Protocol')已设置并且值为https,在这种情况下您知道这是您的协议
  2. 主持人来自req.get('host'),正如Gopal指出

  3. 希望您的网址中不需要非标准端口,但是如果您确实需要知道它,那么您的应用程序状态就是这样,因为它是您传递给app.listen的任何内容服务器启动时间。但是,在非标准端口上进行本地开发的情况下,Chrome似乎在主机标头中包含端口,因此req.get('host')会返回localhost:3000。因此,至少对于标准端口上的生产站点并直接浏览到您的快速应用程序(没有反向代理)的情况,host标题似乎对URL中的端口做了正确的事情。

  4. 路径来自req.originalUrl(感谢@pgrassant)。请注意,此DOES包含查询字符串。 docs here on req.url and req.originalUrl。根据您打算对网址执行的操作,与originalUrl相比,req.url可能是也可能不是正确的值。

  5. 将所有这些组合在一起以重建绝对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.js中的
  1. app.set('trust proxy', 'loopback');
  2. X-Forwarded-Host标头必须由您自己在网络服务器中指定。例如。 apache,nginx
  3. <强> 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 函数中,您将在每条路线中获得相同的结果,因此属性始终固定

属性

enter image description here

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,但您会在客户端浏览器中得到它。 >

文档:https://nodejs.org/api/url.html#url_new_url_input_base

答案 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