416

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
0

19 Answers 19

726
const full = location.protocol + '//' + location.host;
9
  • 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
    Commented Sep 2, 2012 at 6: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
    Commented Oct 5, 2015 at 22:57
  • 1
    Sorry for the late reply, @NickT. Yes, it does't do that. Please, use the nice solution provided by David for that.
    – Shef
    Commented Oct 7, 2015 at 16:37
  • 27
    Can't you use location.host instead of location.hostname + location.port?
    – c24w
    Commented Sep 20, 2016 at 14:28
  • 1
    Upvoting for hinting that location.protocol contains the colon. Commented Aug 30, 2019 at 11:25
228

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' }
9
  • 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
    Commented Sep 26, 2016 at 12:35
  • Are you doing that on a http page perhaps? If not specified it will 'inherit' from the current location Commented Nov 14, 2016 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
    Commented Mar 31, 2017 at 11:30
  • This works well in case of absolute URL. It fails in case of Relative URL and cross-browser. Any suggestions?
    – Gururaj
    Commented Aug 4, 2017 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... Commented Sep 5, 2017 at 3:19
215

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

1
194

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]
4
  • 10
    This works with URL string where location object is not available(js outside browser!) Commented Nov 26, 2014 at 6:03
  • 12
    Or just turn it into a one-liner: window.location.href.split('/').slice(0, 3).join('/') Commented May 16, 2017 at 19:35
  • and how you'd do this on node? Commented May 22, 2017 at 10:49
  • It looks like location.protocol is supported since may 2013. When this answer was made it made sense, for now you could use location.protocol.
    – A1rPun
    Commented Sep 16, 2019 at 14:41
55

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

0
37

host

var url = window.location.host;

returns localhost:2679

hostname

var url = window.location.hostname;

returns localhost

0
27

Why not use:

let full = window.location.origin
2
  • 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. Commented Aug 7, 2019 at 23:13
  • This just repeats the same solution (window.location.origin) as several answers including this one from 2013 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
    Commented Mar 24, 2023 at 16:09
26

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

1
  • This just repeats the same solution (window.location.origin) as several answers including this one from 2013 stackoverflow.com/a/16843537 -- It should be deleted, but requires a moderator due to the high score.
    – TylerH
    Commented Mar 24, 2023 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');
0
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: '');
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: '') }`;
4

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>

3
var http = location.protocol;
var slashes = http.concat("//");
var host = slashes.concat(window.location.hostname);
3
var getBasePath = function(url) {
    var r = ('' + url).match(/^(https?:)?\/\/[^/]+/i);
    return r ? r[0] : '';
};
1
  • 2
    consider explaining your answer. Don't assume the OP can understand the significance of the different parts of your code.
    – ADyson
    Commented Sep 9, 2016 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.

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

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

-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)
1
  • 1
    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
    Commented Mar 29, 2022 at 18:36

Not the answer you're looking for? Browse other questions tagged or ask your own question.