534

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"
3
  • 14
    In case you're working on the current URL, you can access hostname and pathname directly from the location object. Commented Jun 26, 2014 at 14:54
  • 1
    what about "lastPathPart"? Commented Nov 30, 2018 at 15:00
  • Not regex but the Python Module tldextract does this exactly: github.com/john-kurkowski/tldextract Commented May 15, 2019 at 0:20

26 Answers 26

653

The modern way:

new URL("http://example.com/aa/bb/")

Returns an object with properties hostname and pathname, along with a few others, most notably, port and searchParams (prepared instance of URLSearchParams).

Note that host contains both hostname+port,
but hostname only contains the domain (and not the port).

The first argument is a relative or absolute URL; if it's relative, then you need to specify the second argument (the base URL). For example, for a URL relative to the current page:

new URL("/aa/bb/", location)

In addition to browsers, this API is also available in Node.js since v7, through require('url').URL.

Sign up to request clarification or add additional context in comments.

14 Comments

Experimental technology: IE doens't support this! developer.mozilla.org/en-US/docs/Web/API/URL/…
@cwouter: It does work in Edge however, which replaces IE
this is the way to do it, edge is already 3 versions on top of ie so it doesn't matter
@justingordon: The URL class is a Web standard, so non-browsers aren't required to implement it. However, recent versions of Nodejs do provide an identical library, require('url').URL
The fact that JavaScript doesn't have a built-in way to parse URLs that works on browsers or servers is pretty sad...
|
384
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"

18 Comments

Are you sure this is a cross-browser compatible solution?
It should be noted that, while this may help/answer the original poster, this answer will only work for people doing JS work in a browser, since it relies on the DOM to do its work.
Another example of simplicity, alongside ingenuity.
Does not work in IE if the href is relative. l.hostname will be empty. If you're only providing full URL's then this will work.
Even with absolute URLs, IE (tested in IE 11) behaves differently from Chrome and Firefox. IE's pathname removes the leading slash, while the other browsers do not. So you'll end up with /path or path, depending on your browser.
|
337

found here: https://gist.github.com/jlong/2428561

var parser = document.createElement('a');
parser.href = "http://example.com:3000/pathname/?search=test#hash";

parser.protocol; // => "http:"
parser.host;     // => "example.com:3000"
parser.hostname; // => "example.com"
parser.port;     // => "3000"
parser.pathname; // => "/pathname/"
parser.hash;     // => "#hash"
parser.search;   // => "?search=test"
parser.origin;   // => "http://example.com:3000"

10 Comments

Note that if you just want to get the parsed parts of the current browser location, the 1st two lines become parser = location; and all the following lines work. Tried it in Chrome and IE9 just now.
Also note that pathname doesn't include the leading slash in IE. Go figure. :D
For IE, use "/" + parser.pathname
Warning: it will return http: even if you pass just domain.com to href (without any protocol). I wanted to use this to check if the protocol was missing, and if so I could add it, but it assumes http: so was unable to use it for this purpose.
The hostname actually includes the protocol. Test on the latest version of Chrome.
|
139

Here's a simple function using a regexp that imitates the a tag behavior.

Pros

  • predictable behaviour (no cross browser issues)
  • doesn't need the DOM
  • it's really short.

Cons

  • The regexp is a bit difficult to read

-

function getLocation(href) {
    var match = href.match(/^(https?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/);
    return match && {
        href: href,
        protocol: match[1],
        host: match[2],
        hostname: match[3],
        port: match[4],
        pathname: match[5],
        search: match[6],
        hash: match[7]
    }
}

-

getLocation("http://example.com/");
/*
{
    "protocol": "http:",
    "host": "example.com",
    "hostname": "example.com",
    "port": undefined,
    "pathname": "/"
    "search": "",
    "hash": "",
}
*/

getLocation("http://example.com:3000/pathname/?search=test#hash");
/*
{
    "protocol": "http:",
    "host": "example.com:3000",
    "hostname": "example.com",
    "port": "3000",
    "pathname": "/pathname/",
    "search": "?search=test",
    "hash": "#hash"
}
*/

EDIT:

Here's a breakdown of the regular expression

var reURLInformation = new RegExp([
    '^(https?:)//', // protocol
    '(([^:/?#]*)(?::([0-9]+))?)', // host (hostname and port)
    '(/{0,1}[^?#]*)', // pathname
    '(\\?[^#]*|)', // search
    '(#.*|)$' // hash
].join(''));
var match = href.match(reURLInformation);

5 Comments

Doesn't work with any relative URLs. Did you follow RFC-3986 when making the regexp? > getLocation("//example.com/"); null > getLocation("/pathname/?search"); null > getLocation("/pathname/"); null > getLocation("relative"); null
I like how this does not use the DOM, but gregers has a good point. It would be nice if this can handle relative paths. It would require to use window.location (an a element) to fill in the blanks and adding code. In that case, the method would become hypocritical. Unless there is an alternative, not sure how this can be solved perfectly.
Added the href key with original url, this provides consistency on that return object with the dom implementation.
If someone need to parse relative URLs here is the updated regexp: /^(?:(https?\:)\/\/)?(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/
I absolutely love this answer. Doing this with the URL API is trivial, but I'm in a scenario where I cannot leverage that and this just saved me a ton of time figuring out the right regex. Genious!
108
var loc = window.location;  // => "http://example.com:3000/pathname/?search=test#hash"

returns the currentUrl.

If you want to pass your own string as a url (doesn't work in IE11):

var loc = new URL("http://example.com:3000/pathname/?search=test#hash")

Then you can parse it like:

loc.protocol; // => "http:"
loc.host;     // => "example.com:3000"
loc.hostname; // => "example.com"
loc.port;     // => "3000"
loc.pathname; // => "/pathname/"
loc.hash;     // => "#hash"
loc.search;   // => "?search=test"

Comments

66

freddiefujiwara's answer is pretty good but I also needed to support relative URLs within Internet Explorer. I came up with the following solution:

function getLocation(href) {
    var location = document.createElement("a");
    location.href = href;
    // IE doesn't populate all link properties when setting .href with a relative URL,
    // however .href will return an absolute URL which then can be used on itself
    // to populate these additional fields.
    if (location.host == "") {
      location.href = location.href;
    }
    return location;
};

Now use it to get the needed properties:

var a = getLocation('http://example.com/aa/bb/');
document.write(a.hostname);
document.write(a.pathname);

Example:

function getLocation(href) {
  var location = document.createElement("a");
  location.href = href;
  // IE doesn't populate all link properties when setting .href with a relative URL,
  // however .href will return an absolute URL which then can be used on itself
  // to populate these additional fields.
  if (location.host == "") {
    location.href = location.href;
  }
  return location;
};
var urlToParse = 'http://example.com/aa/bb/',
  a = getLocation(urlToParse);
document.write('Absolute URL: ' + urlToParse);
document.write('<br />');
document.write('Hostname: ' + a.hostname);
document.write('<br />');
document.write('Pathname: ' + a.pathname);

5 Comments

This should be the accepted answer. Very clever use of relative-to-absolute URL handling. +1
Apparently not the first time a JSFiddle link died: stackoverflow.com/questions/25179964/…
This worked great, however I had one update that I hope will help others. I'm using this to check origin on a postMessage request and when the port is a default port (80 or 443), it doesn't get appended to the path. I conditionally checked for that when creating my URL: var locationHost = (location.port !== '80' && location.port !== '443') ? location.host : location.hostname; var locationOrigin = location.protocol + '//' + locationHost;
I made this comment elsewhere on a more popular variant of this solution, but as this was my favorite solution, I wanted to repeat it here. In IE11, having a username in the href will cause all these property reads to throw security errors. Example: "example.com" will work just fine. But "[email protected]" or "username:[email protected]" will make any attempt to reference one of the other properties of the anchor element (example: hash) to fail and throw an obnoxious error.
fantastic solution! 👏🏻
18

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

7 Comments

thanks!!! but I want to uri = new Location("example.com/aa/bb") typeof(window.location) == typeof(uri)
Since window.location is a string, I don't really see how that would be possible or helpful. Why do the types need to match when you can easily convert from one to the other?
developer.mozilla.org/en/DOM/window.location is very nice api!! so I hope convert String to window.location object
Setting window.location changes the browser so it is not going to happen.
Hmm that's right. window.location is not a string, but can be assigned from a string. I'm not sure if that can be mimicked, I've tried assigning the prototype of location to a new uri object but that did not work.
|
16

today I meet this problem and I found: URL - MDN Web APIs

var url = new URL("http://test.example.com/dir/subdir/file.html#hash");

This return:

{ hash:"#hash", host:"test.example.com", hostname:"test.example.com", href:"http://test.example.com/dir/subdir/file.html#hash", origin:"http://test.example.com", password:"", pathname:"/dir/subdir/file.html", port:"", protocol:"http:", search: "", username: "" }

Hoping my first contribution helps you !

3 Comments

Duplicate answer
Yeah but the guy at the top just update his awser in 2017, me I post it in 2016.
Ah my bad, sorry
13

What about simple regular expression?

url = "http://www.example.com/path/to/somwhere";
urlParts = /^(?:\w+\:\/\/)?([^\/]+)(.*)$/.exec(url);
hostname = urlParts[1]; // www.example.com
path = urlParts[2]; // /path/to/somwhere

3 Comments

Try to parse something valid like //user:[email protected]/path/x?y=z and you will see why simple regular expression does not cut it. Now throw something invalid to it and it should bail out in predictable way, too.
Simple regex is for simple problems :) But it doesn't sound to me that url like this is unparsable by regex, it would just need few more tweaks. But I'd probably go for some library if I need something more complex and bulletroof though.
I agree with @svestka's comments above, but if you want a simple regex solution and have a trusted source (like I do) and no access to the DOM or URL() (as I'm using tabris.js) then a regex can be the way to go. Here's one that can handle the query string too ^(?:\w+\:\/\/)?([^\/]+)([^\?]*)\??(.*)$
12
function parseUrl(url) {
    var m = (url || sp.targetUrl()).match(/^(([^:\/?#]+:)?(?:\/\/((?:([^\/?#:]*)(?::([^\/?#:]*))?@)?([^\/?#:]*)(?::([^\/?#:]*))?)))?([^?#]*)(\?[^#]*)?(#.*)?$/),
        r = {
            hash: m[10] || "",                   // #asd
            host: m[3] || "",                    // localhost:257
            hostname: m[6] || "",                // localhost
            href: m[0] || "",                    // http://username:password@localhost:257/deploy/?asd=asd#asd
            origin: m[1] || "",                  // http://username:password@localhost:257
            pathname: m[8] || (m[1] ? "/" : ""), // /deploy/
            port: m[7] || "",                    // 257
            protocol: m[2] || "",                // http:
            search: m[9] || "",                  // ?asd=asd
            username: m[4] || "",                // username
            password: m[5] || ""                 // password
        };
    if (r.protocol.length == 2) {
        r.protocol = "file:///" + r.protocol.toUpperCase();
        r.origin = r.protocol + "//" + r.host;
    }
    r.href = r.origin + r.pathname + r.search + r.hash;
    return r;
};
parseUrl("http://username:password@localhost:257/deploy/?asd=asd#asd");

It works with both absolute and relative urls.
To handle relative path as absolute url without schema change regex to /^((?:([^:\/?#]+:)(?:\/\/))?((?:([^\/?#:]*)(?::([^\/?#:]*))?@)?([^\/?#:]*)(?::([^\/?#:]*))?))?([^?#]*)(\?[^#]*)?(#.*)?$/

9 Comments

abc://username:[email protected]:123/path/data?key=value&key2=value2#fragid1
@山茶树和葡萄树 I have updated the code to handle userinfo subcomponent properly. Thanks for your comment, I didn't notice that problem before
love this regex
@MichaelMao That's because absolute urls should always have scheme defined. Anyway I've updated regexp to handle such pseudo-absolute urls, so this is not a problem now. I have no enough time to test this regexp using wide range of urls, but I believe all should works fine.
@Brett I've updated the code and it should work fine now
|
10

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;

}

Comments

7

Cross-browser URL parsing, works around the relative path problem for IE 6, 7, 8 and 9:

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://domain.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;
}

Usage (demo JSFiddle here):

var myUrl = new ParsedUrl("http://www.example.com:8080/path?query=123#fragment");

Result:

{
    hash: "#fragment"
    host: "www.example.com:8080"
    hostname: "www.example.com"
    href: "http://www.example.com:8080/path?query=123#fragment"
    pathname: "/path"
    port: "8080"
    protocol: "http:"
    search: "?query=123"
}

Comments

5

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 : '';
    }

2 Comments

This is a very important thing to consider!
This completely breaks relative urls, though!
4

The AngularJS way - fiddle here: http://jsfiddle.net/PT5BG/4/

<!DOCTYPE html>
<html>
<head>
    <title>Parse URL using AngularJS</title>
</head>
<body ng-app ng-controller="AppCtrl" ng-init="init()">

<h3>Parse URL using AngularJS</h3>

url: <input type="text" ng-model="url" value="" style="width:780px;">

<ul>
    <li>href = {{parser.href}}</li>
    <li>protocol = {{parser.protocol}}</li>
    <li>host = {{parser.host}}</li>
    <li>hostname = {{parser.hostname}}</li>
    <li>port = {{parser.port}}</li>
    <li>pathname = {{parser.pathname}}</li>
    <li>hash = {{parser.hash}}</li>
    <li>search = {{parser.search}}</li>
</ul>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>

<script>
function AppCtrl($scope) {

    $scope.$watch('url', function() {
        $scope.parser.href = $scope.url;
    });

    $scope.init = function() {
        $scope.parser = document.createElement('a');
        $scope.url = window.location;
    }

}
</script>

</body>
</html>

1 Comment

It will be more angular if you will use $document and $window services
4

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

1 Comment

2021 answer: Use new URL('your string url') and you get the same result.
3

Simple and robust solution using the module pattern. This includes a fix for IE where the pathname does not always have a leading forward-slash (/).

I have created a Gist along with a JSFiddle which offers a more dynamic parser. I recommend you check it out and provide feedback.

var URLParser = (function (document) {
    var PROPS = 'protocol hostname host pathname port search hash href'.split(' ');
    var self = function (url) {
        this.aEl = document.createElement('a');
        this.parse(url);
    };
    self.prototype.parse = function (url) {
        this.aEl.href = url;
        if (this.aEl.host == "") {
           this.aEl.href = this.aEl.href;
        }
        PROPS.forEach(function (prop) {
            switch (prop) {
                case 'hash':
                    this[prop] = this.aEl[prop].substr(1);
                    break;
                default:
                    this[prop] = this.aEl[prop];
            }
        }, this);
        if (this.pathname.indexOf('/') !== 0) {
            this.pathname = '/' + this.pathname;
        }
        this.requestUri = this.pathname + this.search;
    };
    self.prototype.toObj = function () {
        var obj = {};
        PROPS.forEach(function (prop) {
            obj[prop] = this[prop];
        }, this);
        obj.requestUri = this.requestUri;
        return obj;
    };
    self.prototype.toString = function () {
        return this.href;
    };
    return self;
})(document);

Demo

var URLParser = (function(document) {
  var PROPS = 'protocol hostname host pathname port search hash href'.split(' ');
  var self = function(url) {
    this.aEl = document.createElement('a');
    this.parse(url);
  };
  self.prototype.parse = function(url) {
    this.aEl.href = url;
    if (this.aEl.host == "") {
      this.aEl.href = this.aEl.href;
    }
    PROPS.forEach(function(prop) {
      switch (prop) {
        case 'hash':
          this[prop] = this.aEl[prop].substr(1);
          break;
        default:
          this[prop] = this.aEl[prop];
      }
    }, this);
    if (this.pathname.indexOf('/') !== 0) {
      this.pathname = '/' + this.pathname;
    }
    this.requestUri = this.pathname + this.search;
  };
  self.prototype.toObj = function() {
    var obj = {};
    PROPS.forEach(function(prop) {
      obj[prop] = this[prop];
    }, this);
    obj.requestUri = this.requestUri;
    return obj;
  };
  self.prototype.toString = function() {
    return this.href;
  };
  return self;
})(document);

/* Main */
var out = document.getElementById('out');
var urls = [
  'https://www.example.org:5887/foo/bar?a=1&b=2#section-1',
  'ftp://www.files.com:22/folder?id=7'
];
var parser = new URLParser();
urls.forEach(function(url) {
  parser.parse(url);
  println(out, JSON.stringify(parser.toObj(), undefined, ' '), 0, '#0000A7');
});

/* Utility functions */
function print(el, text, bgColor, fgColor) {
  var span = document.createElement('span');
  span.innerHTML = text;
  span.style['backgroundColor'] = bgColor || '#FFFFFF';
  span.style['color'] = fgColor || '#000000';
  el.appendChild(span);
}
function println(el, text, bgColor, fgColor) {
  print(el, text, bgColor, fgColor);
  el.appendChild(document.createElement('br'));
}
body {
  background: #444;
}
span {
  background-color: #fff;
  border: thin solid black;
  display: inline-block;
}
#out {
  display: block;
  font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;
  font-size: 12px;
  white-space: pre;
}
<div id="out"></div>

Output

{
 "protocol": "https:",
 "hostname": "www.example.org",
 "host": "www.example.org:5887",
 "pathname": "/foo/bar",
 "port": "5887",
 "search": "?a=1&b=2",
 "hash": "section-1",
 "href": "https://www.example.org:5887/foo/bar?a=1&b=2#section-1",
 "requestUri": "/foo/bar?a=1&b=2"
}
{
 "protocol": "ftp:",
 "hostname": "www.files.com",
 "host": "www.files.com:22",
 "pathname": "/folder",
 "port": "22",
 "search": "?id=7",
 "hash": "",
 "href": "ftp://www.files.com:22/folder?id=7",
 "requestUri": "/folder?id=7"
}

Comments

3

Use https://www.npmjs.com/package/uri-parse-lib for this

var t = parserURI("http://user:[email protected]:8080/directory/file.ext?query=1&next=4&sed=5#anchor");

Comments

3

Why do not use it?

        $scope.get_location=function(url_str){
        var parser = document.createElement('a');
        parser.href =url_str;//"http://example.com:3000/pathname/?search=test#hash";
        var info={
            protocol:parser.protocol,   
            hostname:parser.hostname, // => "example.com"
            port:parser.port,     // => "3000"
            pathname:parser.pathname, // => "/pathname/"
            search:parser.search,   // => "?search=test"
            hash:parser.hash,     // => "#hash"
            host:parser.host, // => "example.com:3000"      
        }
        return info;
    }
    alert( JSON.stringify( $scope.get_location("http://localhost:257/index.php/deploy/?asd=asd#asd"),null,4 ) );

Comments

3

You can also use parse_url() function from Locutus project (former php.js).

Code:

parse_url('http://username:password@hostname/path?arg=value#anchor');

Result:

{
  scheme: 'http',
  host: 'hostname',
  user: 'username',
  pass: 'password',
  path: '/path',
  query: 'arg=value',
  fragment: 'anchor'
}

2 Comments

that url didn't work for me, but i found it over here github.com/hirak/phpjs/blob/master/functions/url/parse_url.js
@StanQuinn, that is because php.js changed it's name to Locutus. I have updated my answer with new link.
2

Stop reinventing the wheel. Use https://github.com/medialize/URI.js/

var uri = new URI("http://example.org:80/foo/hello.html");
// get host
uri.host(); // returns string "example.org:80"
// set host
uri.host("example.org:80");

4 Comments

Because every time you want to solve a problem... use a library? Okay... (not)
Not always (actually almost never) but URLs are very tricky to parse, there are many many details in the RFCs. Better to use a library that has been used and tested by thousands.
How about just use what is built in, instead of having someone else reinvent the wheel with a library? See stackoverflow.com/a/24006120/747739
There is no IE11 support for the built-in function, so this library is excellent. To say never to use a library is like saying we should never have used jQuery and just write native code, which is absolutely ridiculous. Every developer has a different use case, there is no 'best' way, sometimes vanilla/native works best, sometimes it doesn't... something 92% of developers still has to learn.
1

Just use url.js library (for web and node.js).

https://github.com/websanova/js-url

url: http://example.com?param=test#param=again

url('?param'); // test
url('#param'); // again
url('protocol'); // http
url('port'); // 80
url('domain'); // example.com
url('tld'); // com

etc...

Comments

1

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

Comments

0

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

Comments

0

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:[email protected]: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:[email protected]:8080",
  "protocol": "http:",
  "host": "user:[email protected]: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

Comments

0

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'

Comments

-1

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/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.