How to get the full url in Express?
The protocol is available as
req.protocol
. docs here- Before express 3.0, the protocol you can assume to be
http
unless you see thatreq.get('X-Forwarded-Protocol')
is set and has the valuehttps
, in which case you know that's your protocol
- Before express 3.0, the protocol you can assume to be
The host comes from
req.get('host')
as Gopal has indicatedHopefully 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. However, in the case of local development on a non-standard port, Chrome seems to include the port in the host header soreq.get('host')
returnslocalhost:3000
, for example. So at least for the cases of a production site on a standard port and browsing directly to your express app (without reverse proxy), thehost
header seems to do the right thing regarding the port in the URL.The path comes from
req.originalUrl
(thanks @pgrassant). Note this DOES include the query string. docs here on req.url and req.originalUrl. Depending on what you intend to do with the URL,originalUrl
may or may not be the correct value as compared toreq.url
.
Combine those all together to reconstruct the absolute URL.
var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
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
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
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
});
}
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;