605

假设我的示例网址是

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.

4

22 回答 22

892
  1. 该协议可作为req.protocol. 文档在这里

    1. 在 express 3.0 之前,您可以假设的协议,http除非您看到它req.get('X-Forwarded-Protocol')已设置并具有 value https,在这种情况下您知道这是您的协议
  2. req.get('host')正如 Gopal 所指出的,主机来自

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

  4. 路径来自req.originalUrl(感谢@pgrassant)。请注意,这确实包括查询字符串。req.url 和 req.originalUrl 上的文档。根据您打算对 URL 执行的操作,originalUrlreq.url.

将这些组合在一起以重建绝对 URL。

  var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
于 2012-04-17T05:12:03.537 回答
157

您可以将 node.js API 用于 URLURL.format()并从 express传递信息,而不是自己将这些东西连接在一起。

例子:

var url = require('url');

function fullUrl(req) {
  return url.format({
    protocol: req.protocol,
    host: req.get('host'),
    pathname: req.originalUrl
  });
}
于 2013-04-10T09:47:49.493 回答
41

我发现获取请求的 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;
于 2012-10-21T08:06:26.877 回答
21

这是添加函数的好方法,您可以在 req 对象上调用以获取 url

  app.use(function(req, res, next) {
    req.getUrl = function() {
      return req.protocol + "://" + req.get('host') + req.originalUrl;
    }
    return next();
  });

现在你有了一个可以按需调用的函数。

于 2014-03-06T23:07:32.690 回答
18

使用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);
于 2015-08-02T07:24:42.457 回答
13

用这个,

var url = req.headers.host + '/' + req.url;
于 2015-12-31T08:26:35.730 回答
13

使 req.host/req.hostname 生效必须有两个条件Express 后面的代理

  1. app.set('trust proxy', 'loopback');在 app.js 中
  2. 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>
于 2016-06-15T01:58:16.570 回答
12

2021年

上面的答案工作正常,但文档不喜欢,因为url.parse现在是,所以如果你想获得更多的控制权,legacy我建议你使用函数。new URL()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函数中,您将在每条路线中获得相同的结果,因此属性始终是固定的。

特性

在此处输入图像描述

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

于 2021-07-14T05:34:26.253 回答
9

只是下面的代码对我来说就足够了!

const baseUrl = `${request.protocol}://${request.headers.host}`;
// http://127.0.0.1:3333
于 2020-06-04T02:08:01.157 回答
8

我建议使用 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。

于 2014-02-18T19:30:41.200 回答
8
var full_address = req.protocol + "://" + req.headers.host + req.originalUrl;

或者

var full_address = req.protocol + "://" + req.headers.host + req.baseUrl;
于 2017-01-18T10:08:16.070 回答
7

您需要使用req.headers.host + req.url. 当然,如果您在不同的端口托管,那么您就会明白;-)

于 2012-04-17T00:08:00.520 回答
6

我的代码看起来像这样,

params['host_url'] = req.protocol + '://' + req.headers.host + req.url;

于 2013-06-12T08:02:24.690 回答
6

我使用节点包'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/用户名

    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
}
于 2014-10-12T13:56:36.747 回答
6

您可以像这样在路线中使用此功能

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

于 2019-11-19T13:05:58.647 回答
3

谢谢大家提供这些信息。这是令人难以置信的烦人。

将此添加到您的代码中,您将永远不必再考虑它:

var app = express();

app.all("*", function (req, res, next) {  // runs on ALL requests
    req.fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl
        next()
})

您也可以在那里执行或设置其他操作,例如登录到控制台。

于 2019-03-08T21:43:44.993 回答
2

您可以从 express 的 req 中获取完整的 url。

function fetchPages(req, res, next) {

    let fullUrl = req.headers.host + req.originalUrl;
    console.log("full url ==> ",fullUrl);
}
于 2021-12-15T13:18:28.923 回答
1
async function (request, response, next) {
  const url = request.rawHeaders[9] + request.originalUrl;
  //or
  const url = request.headers.host + request.originalUrl;
}
于 2020-12-28T06:05:18.840 回答
0

您可以组合req.protocolreq.hostnamereq.originalUrl。注意req.hostname而不是req.hostreq.get("host")哪个有效但更难阅读。

const completeUrl = `${req.protocol}://${req.hostname}${req.originalUrl}`;
于 2021-11-22T22:32:06.213 回答
-1

通常我依赖这2个,取决于服务器和代理是否存在:

req.socket.remoteAddress

req.headers.referer

于 2021-10-15T02:38:14.470 回答
-2

只需将其放在.env.gitignore 忽略 .env 文件的位置,因此对于每个服务器环境,您将拥有不同的 .env,其中包含该服务器的主机字符串

.env 代码

HOSTNAME=example.com

您想要热名称的文件。

const dotenv = require("dotenv");
dotenv.config();

console.log('hostname: '+process.env.HOSTNAME)

输出:

hostname: example.com
于 2021-12-07T07:36:27.970 回答
-3
const fullUrl = `${protocol}://${host}:${port}${url}`
      
    const responseString = `Full URL is: ${fullUrl}`;                       
    res.send(responseString);  
})
于 2021-11-10T14:13:04.400 回答