'How to get the full URL in Express?

Let's say my sample URL is

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.

How do I get the full URL in Express? For example, in the case above, I would like to receive http://example.com/one/two.



Solution 1:[1]

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.

Example:

var url = require('url');

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

Solution 2:[2]

I found it a bit of a PITA to get the requested url. I can't believe there's not an easier way in express. Should just be 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;

Solution 3:[3]

Here is a great way to add a function you can call on the req object to get the 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.

Solution 4:[4]

In 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.

Express Way

You can get Full URL from the below code.

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

Example URL: 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

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

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

URL Package Way

In the URL function, you will get the same results in every route so properties are always fixed.

Properties

enter image description here

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.

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

Solution 5:[5]

Using 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:

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

Solution 6:[6]

make req.host/req.hostname effective must have two condition when Express behind proxies:

  1. app.set('trust proxy', 'loopback'); in app.js
  2. X-Forwarded-Host header must specified by you own in webserver. eg. 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;
    }
}

apache:

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

Solution 7:[7]

Use this,

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

Solution 8:[8]

Just the code below was enough for me!

const baseUrl = `${request.protocol}://${request.headers.host}`;
// http://127.0.0.1:3333

Solution 9:[9]

I would suggest using originalUrl instead of URL:

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

See the description of originalUrl here: http://expressjs.com/api.html#req.originalUrl

In our system, we do something like this, so originalUrl is important to us:

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

blah_controller looks like this:

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

So our URLs have the format:

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

Hence, we need req.originalUrl in the bar controller get handler.

Solution 10:[10]

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

or

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

Solution 11:[11]

You need to construct it using req.headers.host + req.url. Of course if you are hosting in a different port and such you get the idea ;-)

Solution 12:[12]

I use the node package '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. More info here: 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)

    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:

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
}

Solution 13:[13]

My code looks like this,

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

Solution 14:[14]

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)

Solution 15:[15]

You can get the full url from req of express.

function fetchPages(req, res, next) {

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

Solution 16:[16]

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.

Solution 17:[17]

async function (request, response, next) {
  const url = request.rawHeaders[9] + request.originalUrl;
  //or
  const url = request.headers.host + request.originalUrl;
}

Solution 18:[18]

You can combine req.protocol, req.hostname, and req.originalUrl. Note req.hostname rather than req.host or req.get("host") which works but is harder to read.

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

Solution 19:[19]

I tried to just logged all the data for req

then I found that logging rawHeaders and found all the data available in the url

and I tried this

app.post("/news-letter", (req,res) => {
    console.log(req.body);
    res.redirect(req.rawHeaders[33]);
})

Solution 20:[20]

Usually I rely on these 2, depends on the server and proxy exists:

req.socket.remoteAddress

req.headers.referer