How do I parse a URL into hostname and path in javascript?

Viewed 537886

I would like to take a string

var a = "http://example.com/aa/bb/"

and process it into an object such that

a.hostname == "example.com"

and

a.pathname == "/aa/bb"
26 Answers
var getLocation = function(href) {
    var l = document.createElement("a");
    l.href = href;
    return l;
};
var l = getLocation("http://example.com/path");
console.debug(l.hostname)
>> "example.com"
console.debug(l.pathname)
>> "/path"

js-uri (available on Google Code) takes a string URL and resolves a URI object from it:

var some_uri = new URI("http://www.example.com/foo/bar");

alert(some_uri.authority); // www.example.com
alert(some_uri);           // http://www.example.com/foo/bar

var blah      = new URI("blah");
var blah_full = blah.resolve(some_uri);
alert(blah_full);         // http://www.example.com/foo/blah

Here is a version that I copied from https://gist.github.com/1847816, but rewritten so it's easier to read and debug. The purpose of copying the of the anchor data to another variable named "result" is because the anchor data is pretty long, and so copying a limited number of values to the result will help simplify the result.

/**
 * See: https://gist.github.com/1847816
 * Parse a URI, returning an object similar to Location
 * Usage: var uri = parseUri("hello?search#hash")
 */
function parseUri(url) {

  var result = {};

  var anchor = document.createElement('a');
  anchor.href = url;

  var keys = 'protocol hostname host pathname port search hash href'.split(' ');
  for (var keyIndex in keys) {
    var currentKey = keys[keyIndex]; 
    result[currentKey] = anchor[currentKey];
  }

  result.toString = function() { return anchor.href; };
  result.requestUri = result.pathname + result.search;  
  return result;

}

For those looking for a modern solution that works in IE, Firefox, AND Chrome:

None of these solutions that use a hyperlink element will work the same in chrome. If you pass an invalid (or blank) url to chrome, it will always return the host where the script is called from. So in IE you will get blank, whereas in Chrome you will get localhost (or whatever).

If you are trying to look at the referrer, this is deceitful. You will want to make sure that the host you get back was in the original url to deal with this:

    function getHostNameFromUrl(url) {
        // <summary>Parses the domain/host from a given url.</summary>
        var a = document.createElement("a");
        a.href = url;

        // Handle chrome which will default to domain where script is called from if invalid
        return url.indexOf(a.hostname) != -1 ? a.hostname : '';
    }

Expanded on acdcjunior solution by adding "searchParam" function
Mimicking the URL object, added "searchParam" to parse query string
Works for IE 6, 7, 8 9, 10, 11

USAGE - (JSFiddle Link)

// USAGE:
var myUrl = new ParsedUrl("http://www.example.com/path?var1=123&var2=abc#fragment");
console.log(myUrl);
console.log(myUrl.searchParam('var1'));
console.log(myUrl.searchParam('var2'));

OUTPUT - (JSFiddle Link)

{
  hash: "#fragment",
  host: "www.example.com:8080",
  hostname: "www.example.com",
  href: "http://www.example.com:8080/path?var1=123&amp;var2=abc#fragment",
  pathname: "/path",
  port: "80",
  protocol: "http:",
  search: "?var1=123&amp;var2=abc"
}

"123"
"abc"

CODE - (JSFiddle Link)

function ParsedUrl(url) {
    var parser = document.createElement("a");
    parser.href = url;
    
    // IE 8 and 9 dont load the attributes "protocol" and "host" in case the source URL
    // is just a pathname, that is, "/example" and not "http://www.example.com/example".
    parser.href = parser.href;
    
    // IE 7 and 6 wont load "protocol" and "host" even with the above workaround,
    // so we take the protocol/host from window.location and place them manually
    if (parser.host === "") {
        var newProtocolAndHost = window.location.protocol + "//" + window.location.host;
        if (url.charAt(1) === "/") {
            parser.href = newProtocolAndHost + url;
        } else {
            // the regex gets everything up to the last "/"
            // /path/takesEverythingUpToAndIncludingTheLastForwardSlash/thisIsIgnored
            // "/" is inserted before because IE takes it of from pathname
            var currentFolder = ("/"+parser.pathname).match(/.*\//)[0];
            parser.href = newProtocolAndHost + currentFolder + url;
        }
    }
    
    // copies all the properties to this object
    var properties = ['host', 'hostname', 'hash', 'href', 'port', 'protocol', 'search'];
    for (var i = 0, n = properties.length; i < n; i++) {
      this[properties[i]] = parser[properties[i]];
    }
    
    // pathname is special because IE takes the "/" of the starting of pathname
    this.pathname = (parser.pathname.charAt(0) !== "/" ? "/" : "") + parser.pathname;
  
  //search Params
  this.searchParam =  function(variable) {
    var query = (this.search.indexOf('?') === 0) ? this.search.substr(1) : this.search;
    var vars = query.split('&');
    for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split('=');
        if (decodeURIComponent(pair[0]) == variable) {
            return decodeURIComponent(pair[1]);
        }
    }
    console.log('Query variable %s not found', variable);
    return '';
    };
}

a simple hack with the first answer

var getLocation = function(href=window.location.href) {
    var l = document.createElement("a");
    l.href = href;
    return l;
};

this can used even without argument to figure out the current hostname getLocation().hostname will give current hostname

This doesn't parse the query and hash, but otherwise it works well otherwise.

const getURIParts = (url) => {
  const matches = url.match(/^(\w+?:\/\/)?([\w-\.]+(?=\/?))?:?(\d*)?([^:]*)/)
  return {
    scheme: matches ? matches[1] : undefined,
    host: matches ? matches[2] : '',
    port: matches ? matches[3] : undefined,
    pathname: matches ? matches[4] : ''
  }
}

console.log(getURIParts(""))
console.log(getURIParts("http://localhost/bla"))
console.log(getURIParts("https://api.spotify.com/"))
console.log(getURIParts("https://api.spotify.com"))
console.log(getURIParts("wss://wss.slack.com/link/?ticket=1234-5678"))
console.log(getURIParts("localhost"))
console.log(getURIParts("localhost/bla"))
console.log(getURIParts("localhost/"))
console.log(getURIParts("api.spotify.com/bla/two"))
console.log(getURIParts("api.spotify.com:8000/bla/two"))
console.log(getURIParts("https://api.spotify.com:8800/"))
console.log(getURIParts("/mp3-preview/f504e6b8e037771318656394f532dede4f9bcaea"))

Of course in >2016 the right answer is using URL API
For page URL window.location
And for <a href="..."> HTMLAnchorElement API

Also for supporting older browser, using polyfill:

<script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js?features=URL"></script>

But just as an other option, it can be handle easy and accurate by RegEx pattern:

function URIinfo(s) {
    s=s.match(/^(([^/]*?:)\/*((?:([^:]+):([^@]+)@)?([^/:]{2,}|\[[\w:]+])(:\d*)?(?=\/|$))?)?((.*?\/)?(([^/]*?)(\.[^/.]+?)?))(\?.*?)?(#.*)?$/);
    return {origin:s[1],protocol:s[2],host:s[3],username:s[4],password:s[5],hostname:s[6],port:s[7],path:s[8],folders:s[9],file:s[10],filename:s[11],fileext:s[12],search:s[13],hash:s[14]};
}

var sample='http://user:password@my.site.com:8080/onefolder/folder.name/file.min.js?query=http://my.site.com:8080/file.exe#hash-root:/file/1.txt';

console.log (URIinfo(sample));
/*
{
  "origin": "http://user:password@my.site.com:8080",
  "protocol": "http:",
  "host": "user:password@my.site.com:8080",
  "username": "user",
  "password": "password",
  "hostname": "my.site.com",
  "port": ":8080",
  "path": "/onefolder/folder.name/file.min.js",
  "folders": "/onefolder/folder.name/",
  "file": "file.min.js",
  "filename": "file.min",
  "fileext": ".js",
  "search": "?query=http://my.site.com:8080/file.exe",
  "hash": "#hash-root:/file/1.txt"
}
*/

Work with the RegEx

It is fine with any kind of

  • Absolute / Relative paths
  • IPv4 / IPv6
  • Net protocols / Local Files
  • Query / Hash

And will return all URL options but not searchParams

(+) Also will return file info like PHP pathInfo

Try This :

function getUrlPath(str){
//fakepath when url not have a path
  var fakepath = "/FakPath";
  var url = str+fakepath;
  var reg = /.+?\:\/\/.+?(\/.+?)(?:#|\?|$)/;
  var output = reg.exec(url);
  // check "output" != null
  return (output) ? output[1].replace(fakepath,"") : fakepath;
}

var myurl = "https://stackoverflow.com/questions/736513/";
const path = getUrlPath(myurl);

console.log(   path     );
//output :  /questions/736513/

How about?

'https://stackoverflow.com/questions/736513/how-do-i-parse-a-url-into-hostname-and-path-in-javascript'.split('//').pop().split('/')[0]

Resulting:

'stackoverflow.com'

Related