简体   繁体   English

如何在 Express 中获取完整 URL?

[英]How to get the full URL in Express?

Let's say my sample URL is假设我的示例 URL 是

http://example.com/one/two http://example.com/one/two

and I say I have the following route我说我有以下路线

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

The value of url will be /one/two . url的值将是/one/two

How do I get the full URL in Express?如何在 Express 中获取完整 URL For example, in the case above, I would like to receive http://example.com/one/two .例如,在上面的例子中,我想收到http://example.com/one/two

  1. The protocol is available as req.protocol .该协议可作为req.protocol docs here文档在这里

    1. Before express 3.0, the protocol you can assume to be http unless you see that req.get('X-Forwarded-Protocol') is set and has the value https , in which case you know that's your protocol在 express 3.0 之前,您可以假定协议为http除非您看到req.get('X-Forwarded-Protocol')已设置并具有值https ,在这种情况下,您知道这是您的协议
  2. The host comes from req.get('host') as Gopal has indicated正如 Gopal 所指出的,主机来自req.get('host')

  3. Hopefully you don't need a non-standard port in your URLs, but if you did need to know it you'd have it in your application state because it's whatever you passed to app.listen at server startup time.希望您的 URL 中不需要非标准端口,但如果您确实需要知道它,您将在应用程序状态中使用它,因为它是您在服务器启动时传递给app.listen的任何内容。 However, in the case of local development on a non-standard port, Chrome seems to include the port in the host header so req.get('host') returns localhost:3000 , for example.但是,在非标准端口上进行本地开发的情况下,Chrome 似乎在主机标头中包含该端口,因此req.get('host')返回localhost:3000 ,例如。 So at least for the cases of a production site on a standard port and browsing directly to your express app (without reverse proxy), the host header seems to do the right thing regarding the port in the URL.因此,至少对于标准端口上的生产站点并直接浏览到您的 Express 应用程序(没有反向代理)的情况, host标头似乎对 URL 中的端口做了正确的事情。

  4. The path comes from req.originalUrl (thanks @pgrassant).路径来自req.originalUrl (感谢@pgrassant)。 Note this DOES include the query string.请注意,这确实包括查询字符串。 docs here on req.url and req.originalUrl . req.url 和 req.originalUrl 上的文档 Depending on what you intend to do with the URL, originalUrl may or may not be the correct value as compared to req.url .根据您打算对 URL 执行的操作,与req.url相比, originalUrl可能是也可能不是正确的值。

Combine those all together to reconstruct the absolute URL.将所有这些组合在一起以重建绝对 URL。

  var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;

Instead of concatenating the things together on your own, you could instead use the node.js API for URLs and pass URL.format() the informations from express.您可以将 node.js API 用于 URL并从 express 传递URL.format()信息,而不是自己将这些内容连接在一起。

Example:例子:

var url = require('url');

function fullUrl(req) {
  return url.format({
    protocol: req.protocol,
    host: req.get('host'),
    pathname: req.originalUrl
  });
}

I found it a bit of a PITA to get the requested url.我发现获取请求的 url 有点像 PITA。 I can't believe there's not an easier way in express.我不敢相信快递没有更简单的方法。 Should just be req.requested_url应该只是 req.requested_url

But here's how I set it:但我是这样设置的:

var port = req.app.settings.port || cfg.port;
res.locals.requested_url = req.protocol + '://' + req.host  + ( port == 80 || port == 443 ? '' : ':'+port ) + req.path;

Here is a great way to add a function you can call on the req object to get the url这是添加一个可以在 req 对象上调用以获取 url 的函数的好方法

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

Now you have a function you can call on demand if you need it.现在您有了一个可以按需调用的函数。

Using url.format :使用url.format

var url = require('url');

This support all protocols and include port number.这支持所有协议并包括端口号。 If you don't have a query string in your originalUrl you can use this cleaner solution:如果您的 originalUrl 中没有查询字符串,您可以使用这个更简洁的解决方案:

var requrl = url.format({
    protocol: req.protocol,
    host: req.get('host'),
    pathname: req.originalUrl,
});

If you have a query string:如果您有查询字符串:

var urlobj = url.parse(req.originalUrl);
urlobj.protocol = req.protocol;
urlobj.host = req.get('host');
var requrl = url.format(urlobj);

make req.host/req.hostname effective must have two condition when Express behind proxies :Express 在代理后面时,使 req.host/req.hostname 生效必须有两个条件:

  1. app.set('trust proxy', 'loopback'); in app.js在 app.js 中
  2. X-Forwarded-Host header must specified by you own in webserver. X-Forwarded-Host标头必须由您在网络服务器中指定。 eg.例如。 apache, nginx阿帕奇,nginx

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;
    }
}

apache :阿帕奇

<VirtualHost myhost:80>
    ServerName myhost
    DocumentRoot /path/to/myapp/public
    ProxyPass / http://myapp:8080/
    ProxyPassReverse / http://myapp:8080/
</VirtualHost>

用这个,

var url = req.headers.host + '/' + req.url;

Just the code below was enough for me!只是下面的代码对我来说就足够了!

const baseUrl = `${request.protocol}://${request.headers.host}`;
// http://127.0.0.1:3333
var full_address = req.protocol + "://" + req.headers.host + req.originalUrl;

要么

var full_address = req.protocol + "://" + req.headers.host + req.baseUrl;

You need to construct it using req.headers.host + req.url .您需要使用req.headers.host + req.url构建它。 Of course if you are hosting in a different port and such you get the idea ;-)当然,如果您在不同的端口上托管,那么您就会明白;-)

I would suggest using originalUrl instead of URL:我建议使用 originalUrl 而不是 URL:

var url = req.protocol + '://' + req.get('host') + req.originalUrl;

See the description of originalUrl here: http://expressjs.com/api.html#req.originalUrl在这里查看 originalUrl 的描述: http : //expressjs.com/api.html#req.originalUrl

In our system, we do something like this, so originalUrl is important to us:在我们的系统中,我们做这样的事情,所以 originalUrl 对我们很重要:

  foo = express();
  express().use('/foo', foo);
  foo.use(require('/foo/blah_controller'));

blah_controller looks like this: blah_controller 看起来像这样:

  controller = express();
  module.exports = controller;
  controller.get('/bar/:barparam', function(req, res) { /* handler code */ });

So our URLs have the format:所以我们的 URL 具有以下格式:

www.example.com/foo/bar/:barparam

Hence, we need req.originalUrl in the bar controller get handler.因此,我们需要在 bar 控制器获取处理程序中使用 req.originalUrl。

我的代码看起来像这样,

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

You can use this function in the route like this您可以像这样在路线中使用此功能

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 will give you http or https, req.headers.host will give you the full host name like www.google.com, req.originalUrl will give the rest pathName (in your case /one/two ) req.protocol会给你HTTP或HTTPS, req.headers.host会给你完整的主机名像www.google.com, req.originalUrl把剩下pathName (在你的情况/one/two

I use the node package 'url' (npm install url)我使用节点包“url”(npm install url)

What it does is when you call它的作用是当你打电话时

url.parse(req.url, true, true)

it will give you the possibility to retrieve all or parts of the url.它将使您有可能检索全部或部分 url。 More info here: https://github.com/defunctzombie/node-url更多信息在这里: https : //github.com/defunctzombie/node-url

I used it in the following way to get whatever comes after the / in http://www.example.com/ to use as a variable and pull up a particular profile (kind of like facebook: http://www.facebook.com/username )我以以下方式使用它来获取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);

Though for this to work, you have to create your route this way in your server.js file:尽管要使其正常工作,您必须在 server.js 文件中以这种方式创建路由:

self.routes['/:username'] = require('./routes/users');

And set your route file this way:并以这种方式设置您的路由文件:

router.get('/:username', function(req, res) {
 //here comes the url parsing code
}

Thank you all for this information.谢谢大家提供这些信息。 This is incredibly annoying.这是令人难以置信的烦人。

Add this to your code and you'll never have to think about it again:将此添加到您的代码中,您将永远不必再考虑它:

var app = express();

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

You can do or set other things there as well, such as log to console.你也可以在那里做或设置其他的东西,比如登录到控制台。

I actually discovered that by using this code below you can get your url. 我实际上发现,通过使用下面的代码,您可以获取您的网址。 Then proceed to slicing it up and deciding what next. 然后将其切成薄片,然后决定下一步。

app.use(function(req, res, next) {
console.log(req.originalUrl);
res.send(req.originalUrl);
  });
async function (request, response, next) {
  const url = request.rawHeaders[9] + request.originalUrl;
  //or
  const url = request.headers.host + request.originalUrl;
}

In 2021 2021年

The above answers are working fine but not preferred by the Documentation because url.parse is now legacy so I suggest you to use new URL() function if you want to get more control on url .上面的答案工作正常,但不是文档的首选,因为url.parse现在是legacy所以我建议你使用new URL()函数,如果你想获得更多的控制url

Express Way高速公路

You can get Full URL from the below code.您可以从以下代码中获取Full URL

`${req.protocol}://${req.get('host')}${req.originalUrl}`

Example URL: http://localhost:5000/a/b/c?d=true&e=true#f=false示例网址:http://localhost:5000/a/b/c?d=true&e=true#f=false

Fixed Properties ( you will get the same results in all routes )固定属性(您将在所有路线中获得相同的结果)

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' }

Not Fixed Properties ( will change in every route because it controlled by express itself )不固定的属性(会在每条路线中改变,因为它由表达本身控制)

Route: /路线: /

req.baseUrl: <blank>
req.url: /a/b/c?d=true&e=true
req.path: /a/b/c

Route /a路线/a

req.baseUrl: /a
req.url: /b/c?d=true&e=true
req.path: /b/c

Documentation: http://expressjs.com/en/api.html#req.baseUrl文档: http : //expressjs.com/en/api.html#req.baseUrl

URL Package Way URL打包方式

In the URL function, you will get the same results in every route so properties are always fixed .URL函数中,您将在每个路由中获得相同的结果,因此属性始终是固定的

Properties特性

在此处输入图片说明

const url = new URL(`${req.protocol}://${req.get('host')}${req.originalUrl}`);
console.log(url)

You will get the results like the below.您将得到如下所示的结果。 I changed the order of the properties as per the image so it can match the image flow.我根据图像更改了属性的顺序,以便它可以匹配图像流。

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: ''
}

Note : Hash can not send to the server because it treats as Fragment in the server but you will get that in the client-side means browser.注意Hash无法发送到服务器,因为它在服务器中被视为Fragment ,但您会在客户端浏览器中得到它。

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

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

req.socket.remoteAddress

req.headers.referer

const fullUrl = `${protocol}://${host}:${port}${url}`
      
    const responseString = `Full URL is: ${fullUrl}`;                       
    res.send(responseString);  
})

You can combine req.protocol , req.hostname , and req.originalUrl .您可以组合req.protocolreq.hostnamereq.originalUrl Note req.hostname rather than req.host or req.get("host") which works but is harder to read.请注意req.hostname而不是req.hostreq.get("host") ,它们有效但更难阅读。

const completeUrl = `${req.protocol}://${req.hostname}${req.originalUrl}`;

Simply put it in .env where .env file is ignored by .gitignore so for each server environment you'll be having different .env with host string of that server in it只需将它放在.env ,其中 .env 文件被 .gitignore 忽略,因此对于每个服务器环境,您将拥有不同的 .env 和该服务器的主机字符串

.env code .env 代码

HOSTNAME=example.com

file where you want hotname.您想要 hotname 的文件。

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

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

OUTPUT:输出:

hostname: example.com

You can get the full url from req of express.您可以从 express 的 req 中获取完整的 url。

function fetchPages(req, res, next) {

    let fullUrl = req.headers.host + req.originalUrl;
    console.log("full url ==> ",fullUrl);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM