398

I need to extract the full protocol, domain, and port from a given URL. For example:

https://localhost:8181/ContactUs-1.0/contact?lang=it&report_type=consumer
>>>
https://localhost:8181
codeforester
  • 39,467
  • 16
  • 112
  • 140
yelo3
  • 5,613
  • 5
  • 26
  • 23

19 Answers19

710
const full = location.protocol + '//' + location.host;
Kirill Kulakov
  • 10,035
  • 9
  • 50
  • 67
Shef
  • 44,808
  • 15
  • 79
  • 90
  • 3
    @Randomblue What about it? You will get `about://`. However, I am curious to know, what would be the use case for `about:blank`? I am not sure if any browser injects plugin resources in `about:blank`, but seems like that could be the only use case. – Shef Sep 02 '12 at 06:27
  • 3
    This doesn't work at all if you have a URL string, right? (i.e. you need to be *at* `location` for this to work) – Nick T Oct 05 '15 at 22:57
  • 1
    Sorry for the late reply, @NickT. Yes, it does't do that. Please, use the [**nice solution provided by David**](http://stackoverflow.com/a/26434126/645186) for that. – Shef Oct 07 '15 at 16:37
  • 26
    Can't you use `location.host` instead of `location.hostname` + `location.port`? – c24w Sep 20 '16 at 14:28
  • 1
    Upvoting for hinting that `location.protocol` contains the colon. – Anders Lindén Aug 30 '19 at 11:25
  • 1
    What about `window.origin`? Looks exactly like the output asked for ... – bene-we Sep 10 '21 at 15:30
  • location is not defined ... – Ali Yar Khan Dec 07 '21 at 10:35
  • Works only from a web browser but node or others ES interfaces does not work. – e-info128 Mar 29 '22 at 18:37
  • @bene-we If you mean `window.location.origin` then you are correct! https://developer.mozilla.org/en-US/docs/Web/API/Location/origin – MEMark Aug 06 '22 at 11:10
224

None of these answers seem to completely address the question, which calls for an arbitrary url, not specifically the url of the current page.

Method 1: Use the URL API (caveat: no IE11 support)

You can use the URL API (not supported by IE11, but available everywhere else).

This also makes it easy to access search params. Another bonus: it can be used in a Web Worker since it doesn't depend on the DOM.

const url = new URL('http://example.com:12345/blog/foo/bar?startIndex=1&pageSize=10');

Method 2 (old way): Use the browser's built-in parser in the DOM

Use this if you need this to work on older browsers as well.

//  Create an anchor element (note: no need to append this element to the document)
const url = document.createElement('a');
//  Set href to any path
url.setAttribute('href', 'http://example.com:12345/blog/foo/bar?startIndex=1&pageSize=10');

That's it!

The browser's built-in parser has already done its job. Now you can just grab the parts you need (note that this works for both methods above):

//  Get any piece of the url you're interested in
url.hostname;  //  'example.com'
url.port;      //  12345
url.search;    //  '?startIndex=1&pageSize=10'
url.pathname;  //  '/blog/foo/bar'
url.protocol;  //  'http:'

Bonus: Search params

Chances are you'll probably want to break apart the search url params as well, since '?startIndex=1&pageSize=10' isn't too useable on its own.

If you used Method 1 (URL API) above, you simply use the searchParams getters:

url.searchParams.get('startIndex');  // '1'

Or to get all parameters:

function searchParamsToObj(searchParams) {
  const paramsMap = Array
    .from(url.searchParams)
    .reduce((params, [key, val]) => params.set(key, val), new Map());
  return Object.fromEntries(paramsMap);
}
searchParamsToObj(url.searchParams);
// -> { startIndex: '1', pageSize: '10' }

If you used Method 2 (the old way), you can use something like this:

// Simple object output (note: does NOT preserve duplicate keys).
var params = url.search.substr(1); // remove '?' prefix
params
    .split('&')
    .reduce((accum, keyval) => {
        const [key, val] = keyval.split('=');
        accum[key] = val;
        return accum;
    }, {});
// -> { startIndex: '1', pageSize: '10' }
David Calhoun
  • 8,315
  • 4
  • 30
  • 23
  • link.protocol gets me a "http:" if i inspect a anker with "google.com" :-( ```var link = document.createElement('a'); link.setAttribute('href', 'google.com'); console.log(link.protocol)``` – eXe Sep 26 '16 at 12:35
  • Are you doing that on a `http` page perhaps? If not specified it will 'inherit' from the current location – Stijn de Witt Nov 14 '16 at 21:24
  • Thank you for this clever trick! I would like to add one thing: There is both `host` and `hostname`. The former includes the port (e.g. `localhost:3000`), while the latter is only the host's name (e.g. `localhost`). – codener Mar 31 '17 at 11:30
  • This works well in case of absolute URL. It fails in case of Relative URL and cross-browser. Any suggestions? – Gururaj Aug 04 '17 at 12:42
  • `search = search.split('?')[1];` really?!?! How about `search = search.substr(1);` instead? Much safer and faster since it creates 1 string instead of 2... – Alexis Wilke Sep 05 '17 at 03:19
  • maybe you should include in your answer that [URL.origin](https://developer.mozilla.org/en-US/docs/Web/API/URL/origin) is the relevant property the OP is looking for. it gives you `scheme+host+port`. – Felix K. Aug 26 '18 at 17:40
  • The core you've wrote for the "old way", using "Method 2" that is described as "Use this if you need this to work on older browsers as well.", will **not** work in any old browser. You're using fat-arrow notation `(...) => { [...] }`, `const` and descructive assignment `[key, val] = [...]`. All of those are new to ES6. Older browsers (IE11 and older) can't use it in any way without a tool like babel (https://babeljs.io/). – Ismael Miguel Aug 27 '18 at 11:11
  • @IsmaelMiguel That's sort of implied. ES6 is a 3+ year old standard at this point, and most companies are running transpilers. Please convert the code on your own where needed. – David Calhoun Aug 28 '18 at 04:22
  • The thing is .... I don't need. But writting a method for older browsers and then writting it's implementation using a technology that isn't available for older browsers is kinda strange to me. Also, on the 2nd method, you have `var parms = [...]`, which should be `var params = [...]`. For browsers without ES6, one can use this: https://pastebin.com/BMfjLMwV (polyfil available in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce for IE8 or older). – Ismael Miguel Aug 28 '18 at 09:22
204

For some reason all the answers are all overkills. This is all it takes:

window.location.origin

More details can be found here: https://developer.mozilla.org/en-US/docs/Web/API/window.location#Properties

Pijusn
  • 11,025
  • 7
  • 57
  • 76
  • 3
    Just to complete: location is [defined on HTML5](http://www.w3.org/TR/html5/browsers.html#location) and it implements the `URLUtils` interface which is [defined on WHATWG](https://url.spec.whatwg.org/#urlutils) and includes the `origin` attribute. – Ciro Santilli OurBigBook.com Nov 10 '14 at 09:00
191

first get the current address

var url = window.location.href

Then just parse that string

var arr = url.split("/");

your url is:

var result = arr[0] + "//" + arr[2]
starball
  • 20,030
  • 7
  • 43
  • 238
wezzy
  • 5,897
  • 3
  • 31
  • 42
54

As has already been mentioned there is the as yet not fully supported window.location.origin but instead of either using it or creating a new variable to use, I prefer to check for it and if it isn't set to set it.

For example;

if (!window.location.origin) {
  window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');
}

I actually wrote about this a few months back A fix for window.location.origin

Jeffrey Knight
  • 5,888
  • 7
  • 39
  • 49
Toby
  • 8,483
  • 13
  • 45
  • 68
36

host

var url = window.location.host;

returns localhost:2679

hostname

var url = window.location.hostname;

returns localhost

Miroslav Holec
  • 3,139
  • 25
  • 22
27

Why not use:

let full = window.location.origin
Maik de Kruif
  • 447
  • 6
  • 9
  • 4
    When adding an answer to an older question with existing answers it is useful to explain what new information your answer brings, and to acknowledge if the passage of time impacts the answer. – Jason Aller Aug 07 '19 at 23:13
  • This just repeats the same solution (window.location.origin) as several answers including this one from 2013 https://stackoverflow.com/a/16843537 (the only difference is it assigns the value to a variable, which is irrelevant to the question being asked). It should be deleted, but requires a moderator due to the high score. – TylerH Mar 24 '23 at 16:09
26

window.location.origin will be enough to get the same.

probablyup
  • 7,636
  • 1
  • 27
  • 40
int soumen
  • 521
  • 5
  • 14
  • This just repeats the same solution (window.location.origin) as several answers including this one from 2013 https://stackoverflow.com/a/16843537 -- It should be deleted, but requires a moderator due to the high score. – TylerH Mar 24 '23 at 16:09
16

The protocol property sets or returns the protocol of the current URL, including the colon (:).

This means that if you want to get only the HTTP/HTTPS part you can do something like this:

var protocol = window.location.protocol.replace(/:/g,'')

For the domain you can use:

var domain = window.location.hostname;

For the port you can use:

var port = window.location.port;

Keep in mind that the port will be an empty string if it is not visible in the URL. For example:

If you need to show 80/443 when you have no port use

var port = window.location.port || (protocol === 'https' ? '443' : '80');
9

Indeed, window.location.origin works fine in browsers following standards, but guess what. IE isn't following standards.

So because of that, this is what worked for me in IE, FireFox and Chrome:

var full = location.protocol+'//'+location.hostname+(location.port ? ':'+location.port: '');

but for possible future enhancements which could cause conflicts, I specified the "window" reference before the "location" object.

var full = window.location.protocol+'//'+window.location.hostname+(window.location.port ? ':'+window.location.port: '');
cpu
  • 567
  • 4
  • 6
8

Here is the solution I'm using:

const result = `${ window.location.protocol }//${ window.location.host }`;

EDIT:

To add cross-browser compatibility, use the following:

const result = `${ window.location.protocol }//${ window.location.hostname + (window.location.port ? ':' + window.location.port: '') }`;
JulienRioux
  • 2,853
  • 2
  • 24
  • 37
3
var http = location.protocol;
var slashes = http.concat("//");
var host = slashes.concat(window.location.hostname);
Elankeeran
  • 6,134
  • 9
  • 40
  • 57
3
var getBasePath = function(url) {
    var r = ('' + url).match(/^(https?:)?\/\/[^/]+/i);
    return r ? r[0] : '';
};
haipeng
  • 31
  • 4
  • 2
    consider explaining your answer. Don't assume the OP can understand the significance of the different parts of your code. – ADyson Sep 09 '16 at 10:00
3

Try use a regular expression (Regex), which will be quite useful when you want to validate / extract stuff or even do some simple parsing in javascript.

The regex is :

/([a-zA-Z]+):\/\/([\-\w\.]+)(?:\:(\d{0,5}))?/

Demonstration:

function breakURL(url){

     matches = /([a-zA-Z]+):\/\/([\-\w\.]+)(?:\:(\d{0,5}))?/.exec(url);

     foo = new Array();

     if(matches){
          for( i = 1; i < matches.length ; i++){ foo.push(matches[i]); }
     }

     return foo
}

url = "https://www.google.co.uk:55699/search?q=http%3A%2F%2F&oq=http%3A%2F%2F&aqs=chrome..69i57j69i60l3j69i65l2.2342j0j4&sourceid=chrome&ie=UTF-8"


breakURL(url);       // [https, www.google.co.uk, 55699] 
breakURL();          // []
breakURL("asf");     // []
breakURL("asd://");  // []
breakURL("asd://a"); // [asd, a, undefined]

Now you can do validation as well.

ed9w2in6
  • 133
  • 7
  • "A valid RFC 3986 URL scheme must consist of "a letter and followed by any combination of letters, digits, plus ("+"), period ("."), or hyphen ("-")." -- https://stackoverflow.com/a/9142331/188833 (Here's an urn:ietf:rfc:3897 (URI) / urn:ietf:rfc:3897 (IRI) regex for the scheme: part of a URI/IRI in Python: https://github.com/dgerber/rfc3987/blob/master/rfc3987.py#L147 ) – Wes Turner Jun 13 '18 at 15:45
3

With ES6 template literals:

const url = `${location.protocol}//${location.hostname}${location.port?':'+location.port:''}`;

document.getElementById("result").innerText = url;
<div id="result"></div>

And you can simplify to:

const url = `${location.protocol}//${location.host}`;

document.getElementById("result").innerText = url;
<div id="result"></div>
Craigo
  • 3,384
  • 30
  • 22
2

Simple answer that works for all browsers:

let origin;

if (!window.location.origin) {
  origin = window.location.protocol + "//" + window.location.hostname + 
     (window.location.port ? ':' + window.location.port: '');
}

origin = window.location.origin;
Mike Hawes
  • 555
  • 5
  • 8
1

ES6 style with configurable parameters.

/**
 * Get the current URL from `window` context object.
 * Will return the fully qualified URL if neccessary:
 *   getCurrentBaseURL(true, false) // `http://localhost/` - `https://localhost:3000/`
 *   getCurrentBaseURL(true, true) // `http://www.example.com` - `https://www.example.com:8080`
 *   getCurrentBaseURL(false, true) // `www.example.com` - `localhost:3000`
 *
 * @param {boolean} [includeProtocol=true]
 * @param {boolean} [removeTrailingSlash=false]
 * @returns {string} The current base URL.
 */
export const getCurrentBaseURL = (includeProtocol = true, removeTrailingSlash = false) => {
  if (!window || !window.location || !window.location.hostname || !window.location.protocol) {
    console.error(
      `The getCurrentBaseURL function must be called from a context in which window object exists. Yet, window is ${window}`,
      [window, window.location, window.location.hostname, window.location.protocol],
    )
    throw new TypeError('Whole or part of window is not defined.')
  }

  const URL = `${includeProtocol ? `${window.location.protocol}//` : ''}${window.location.hostname}${
    window.location.port ? `:${window.location.port}` : ''
  }${removeTrailingSlash ? '' : '/'}`

  // console.log(`The URL is ${URL}`)

  return URL
}
Sébastien
  • 1,749
  • 1
  • 15
  • 19
1

window.location.protocol + '//' + window.location.host

Code_Worm
  • 4,069
  • 2
  • 30
  • 35
-1
console.log(`${req.protocol}://${req.get('host')}/${req.originalUrl}`);
  • req.protocol - gives the protocol you used (e.g. HTTP)
  • req.get(host) - gives the host name with the port number (e.g. localhost:8080)
double-beep
  • 5,031
  • 17
  • 33
  • 41
  • But what is req?, the question doesn't have an Express framework tag, for example you might need for an application via CLI to parse URLs. – e-info128 Mar 29 '22 at 18:36