Skip to content
Create a gist now

Instantly share code, notes, and snippets.

URI Parsing with Javascript
var parser = document.createElement('a');
parser.href = "http://example.com:3000/pathname/?search=test#hash";
parser.protocol; // => "http:"
parser.hostname; // => "example.com"
parser.port; // => "3000"
parser.pathname; // => "/pathname/"
parser.search; // => "?search=test"
parser.hash; // => "#hash"
parser.host; // => "example.com:3000"
@jasonrhodes

This is genius and amazingly simple. Only thing is that when I run through it, parser.host outputs "example.com:3000" with the port included. I was running it in Google Chrome's console…

@jlong
Owner
jlong commented Apr 21, 2012

Ah, good point. Updated gist. Try hostname.

@txdv
txdv commented Apr 23, 2012

github needs a like and a share button

@dcaliri
dcaliri commented Apr 23, 2012

nice

@docluv
docluv commented Apr 23, 2012

what about Querystring parameters. Also you can do this with the page's URL using window.location FWIW. Did not think about dropping an anchor on the page for a general url parse though.

@vman
vman commented Apr 23, 2012

This is why I love JavaScript!

@getify
getify commented Apr 23, 2012

if you're looking for something a little more robust (that handles all the querystring stuff pretty reliably), I think this is the canonical best solution: http://blog.stevenlevithan.com/archives/parseuri

@dlee
dlee commented Apr 23, 2012

@getify What's unreliable about this gist that you need something "a little more robust"?

@getify
getify commented Apr 23, 2012

@dlee

  1. parseURI splits up the query string into a hash/array so you don't have to do your own parsing of it, which is often quite error prone.
  2. parseURI works in non-DOM situations (like web workers, node.js, etc)
  3. if you set a partial URL into a link in the DOM of a browser, it will automatically canonicalize the URL to the page (relative to domain, protocol, etc). This might be what you want, or it might not. You have no choice with links, but parseURI can handle some partial URLs in a standalone way without that automatic behavior (if that's what you need, which I sometimes do).
@kamranayub

This is awesomely simple. I use URI.js so I can get an object hash of the query string parameters but this snippet works great for times when you don't want to bring in yet another library.

@jackmasa

Try parse jar://xxxxxx in firefox :D

@nikola
nikola commented Apr 25, 2012

FWIW, Jed Schmidt documented this technique last year during a presentation.

@jed
jed commented Apr 27, 2012

i rolled this trick into a nice 140-byte snippet last year.

@joezimjs
joezimjs commented May 6, 2012

Does anyone have a compatibility list for this method? Does it work on all browsers since IE6?

@rwhitman
rwhitman commented May 7, 2012

How long has this existed?

@mmastrac
mmastrac commented May 7, 2012

This code won't work as-is in IE6, unfortunately (though it does work in IE8, so you may be able to get by as-is, dependent on your minimum version requirements!)

In my experience, setting href on anchor elements dynamically won't work on IE6, as it only processes the href property when running through the HTML parser. I came across a technique a few years ago to do this across all modern browsers by creating a wrapper element and using innerHTML to trigger IE's parser code path:

http://grack.com/blog/2009/11/17/absolutizing-url-in-javascript/

function canonicalize(url) {
    var div = document.createElement('div');
    div.innerHTML = "<a></a>";
    div.firstChild.href = url; // Ensures that the href is properly escaped
    div.innerHTML = div.innerHTML; // Run the current innerHTML back through the parser
    return div.firstChild.href; 
}
@jayzeng
jayzeng commented May 7, 2012

:+1: this is simple and elegant!

@tantalor
tantalor commented May 7, 2012

@jayzeng: it's neither. It's not simple because it requires instantiating DOM elements unnecessarily. It's not elegant because it is unreliable. It is a hack.

I'm trolling at this point, but it's also incorrect because the protocol should be "http", not "http:".

@liunian
liunian commented May 9, 2012

The pathname is pathname/ in ie, while /pathname/ in Chrome.

And it will be /pathname/ if we use document.location.pathname in ie.

@subtleGradient

Where's the Like button?
/me Likes @rpflorence's comment
RegExp FTW

@subtleGradient
<a href=.. onmouseover="location=href">lol, html</a>
@kamranayub

I added URI.js to @rpflorence's jsperf. Seems to be a decent balance between speed and ease of API consumability.

http://jsperf.com/url-parsing/2

@JamieMason

Just a note, got bitten when using this - there are some differences between browser implementations of HTMLAnchorElement@pathname

@compwright

James Padolsey has fixed some of the inconsistencies mentioned and wrapped it all in a nice function. See http://james.padolsey.com/javascript/parsing-urls-with-the-dom/

@p01
p01 commented Sep 6, 2012

This approach not only parses the URL but also resolves it relative to the document/base.

@paulirish

Keep in mind that these definitions may not be consistent with other definitions of the same terms: http://tantek.com/2011/238/b1/many-ways-slice-url-name-pieces

That said, yes, this rocks. :)

@MoOx
MoOx commented Sep 6, 2012

I've made a tiny js helper to do that, a year ago https://github.com/MoOx/Url.js

@zaus
zaus commented Oct 24, 2012

and yet another jsperf fork -- wrapping the regex in a "nicer" return format, almost as good performance: http://jsperf.com/url-parsing/5

@SamFleming

In Internet Explorer it appears that if using a relative URL and trying to use parser.hostname it will return a blank string.

See test case here http://jsbin.com/eqoruj/2/edit. If visited in IE you'll see Window: jsbin.com compared to any other browser which shows Parser: jsbin.com.

var parser = document.createElement('a');
parser.href = '/relative/url';
console.log(parser.hostname); // IE = "", Other browsers = window.location.hostname.

You can get around this using

parser.hostname || window.location.hostname
@donatj
donatj commented Dec 26, 2012

So useful, you just made my day good sir!

@fetmar
fetmar commented Feb 27, 2013

This is amazing. Thank you. Is there a way to get the username and password if that was supplied? Like

parser.href = "http://user:pass@www.test.com/";

parser.hostname only returns "www.test.com"

@jlong
Owner
jlong commented Feb 27, 2013

@fetmar from what I can tell there isn't a way to get the username and password using this method. For that try URI.js.

@epoberezkin

That's a shame, but it doesn't work in IE9... Had to switch back to regexp. Should've read all comments, it would save me 20 minutes debugging... :)

@aymanfarhat

Nice snippet, inspired by your method I built a more complete function for breaking down any string URI to an object with attributes in javascript. Including breaking down the url parameters to a set of key value pairs, accounting for multiple values of a key, and converting parameter types that are numbers back to numbers from string. You can check it out here https://gist.github.com/aymanfarhat/5347921 enjoy!

@jatinder85

Wow...this is soo amazing. One of our dev guys has written like 500 line long object to cover all the scenarios for parsing a URI using regex. I guess i will just throw that code away and will be happy to use this and normalize it for all browsers.

@megatolya

How about punycode?

var parser = document.createElement('a');
parser.href = "ололо.рф";
parser.hostname // => lgjclffcjaeimfimpcjkgbojfgehfopl  :(
@drudru
drudru commented Sep 5, 2013

Nice trick!

@khhhshhh

Code below also works, that might be useful while using postMessage.

parser.origin
@sairion
sairion commented Oct 20, 2013

I wrote a function that returns object, which contains parameter values in current URL.

https://gist.github.com/sairion/7065921

@pbojinov
pbojinov commented Jan 9, 2014

Found myself using anchor.hostname more frequently and came across this jsperf comparing the number of operations against a regex check - http://jsperf.com/get-hostname-from-url

@zzz6519003

I dig those gists which i can understand~~~~~~~

@sean9999
sean9999 commented Apr 2, 2014

:heart:

@a0xnirudh

I have a variable (named "link") which contains a URL. The variable is modified occasionally through out the program. but modifying the above program as

parser.href = link

won't do the trick. Can anyone help me with this ?

thanks !

@sean9999

@lucif3rr, you probably don't need this code. if you want to change an <a> elements href attribute, and you have the value already, all you need is something like this:

<a id="x" href="about:blank">go to thing</a>
var myvar = 'http://google.ca';
var a = document.getElementById('x');
a.href = myvar;
@tylergraf

Woooooooo!!!!! This is Rad!

@HaNdTriX

FYI:

new URL('https://gist.github.com/jlong/2428561?foo=bar#test') =>
    {
        hash: "#test",
        search: "?foo=bar",
        pathname: "/jlong/2428561",
        port: "",
        hostname: "gist.github.com",
        host: "gist.github.com",
        password: "",
        username: "",
        protocol: "https:",
        origin: "https://gist.github.com",
        href: "https://gist.github.com/jlong/2428561?foo=bar#test"
    }
@sadams
sadams commented Jul 2, 2014

I pinched rpflorence regex (sorry!), tweaked it a bit and made a lib to replicate the native new URL() API using pure regex:
https://github.com/sadams/lite-url
more detail on the final regex:
http://stackoverflow.com/a/24527267/1584651

@foxx
foxx commented Jul 8, 2014

Beautiful, just beautiful.

@mjackson
mjackson commented Aug 7, 2014

You've also got username and password properties:

var a = document.createElement('a');
a.href = 'http://user:pass@example.com';
a.username; // user
a.password; // pass
@arkadylukashov

amazing

@farico
farico commented Aug 19, 2014

<3

@miguelmota

Thumbs up

@arapehl
arapehl commented Aug 25, 2014

Brilliant

@z4r
z4r commented Aug 27, 2014

:thumbsup:

@usandfriends

URL macro from here.

/*
 * Simple getter that parses URL.prototype.search.
 * Caution: Does not protect against non-escaped characters in values.
 */
URL.prototype.__defineGetter__('query', function() {
  var parsed = this.search.substr(1).split('&');

  parsed.forEach(function(elem, iter, arr) {
    var vals = arr[iter].split('=');
    arr[iter] = {
      key: vals[0],
      value: vals[1]
    };
  });

  return parsed;
});

/*
 * new URL('https://gist.github.com/jlong/2428561?foo=bar#test').query ==>
 *     [
 *          {
 *               key: 'foo',
 *               value: 'bar'
 *          }
 *     ]
 */
@redconfetti

This is why I :heart: jQuery

@RyanNutt

Thanks for this. Very nice and easy.

@chuyik
chuyik commented Nov 25, 2014

Awesome trick!!

@TWiStErRob

You can also modify properties, so no need to read them one by one and join them again:

// changing a property (everything else stays as was \o/)
parser.hostname = "www.example.com";
// parser.href == "http://www.example.com:3000/pathname/?search=test#hash"

// adding a new previously non-existent property (notice I didn't write @)
parser.username = "user";
// parser.href == "http://user@www.example.com:3000/pathname/?search=test#hash"

// removing an existing one (=null and =undefined would output "null" and "undefined")
parser.search = "";
// parser.href == "http://user@www.example.com:3000/pathname/#hash"

@jlong please update with username/password and this fact!

@disjukr
disjukr commented Dec 16, 2014

so sweet :D

@stefanb
stefanb commented Jan 8, 2015

This is not working in IE11.
both parser.protocol and parser.host are empty.

Snippet:

    var parser = document.createElement('a');
    parser.href = "foo.html";
    if (parser.protocol != document.location.protocol || parser.host != document.location.host) {
        alert('other: \n' + parser.href +" (" + parser.protocol + ", "+  parser.host + ") != \n" + document.location+" (" + document.location.protocol + ", "+  document.location.host + ")");
    } else {
        alert('same');
    }

(available for test at: http://jsfiddle.net/v7sktaLw/4/ )

correctly reports 'same' in Firefox and Chrome, but in IE11 it reports:

other:
http://fiddle.jshell.net/v7sktaLw/4/show/foo.html (, ) !=
http://fiddle.jshell.net/v7sktaLw/4/show/ (http:, fiddle.jshell.net)

@lucjan
lucjan commented Jan 21, 2015

@HaNdTriX This won't work in any IE though?

@gondo
gondo commented Jan 29, 2015

be careful about relative vs absolute urls.
if url doesn't start with http:// than the url is considered to be relative url.
f.e.:

var parser = document.createElement('a');
parser.href = "www.google.com";
parser.href; // "https://gist.github.com/jlong/www.google.com"

parser.href = "http://www.google.com";
parser.href; // "https://www.google.com"

@nyurik
nyurik commented Feb 20, 2015

Relative protocol URLs seem to be broken - defunctzombie/node-url#5 . For example, //example.com/path is incorrectly parsed as one big pathname.

@nevir
nevir commented Feb 26, 2015

@najamelan URL is a pretty recent thing (check the compatibility table for it - IE10+, etc)

@AlicanC
AlicanC commented Mar 7, 2015

Try these:

myproto:file.ext
Chrome puts "file.ext" in pathname while Firefox leaves it empty.

path/to/file.ext
If you use window.URL, you will get an exception. If you use an <a>, you will get "http://yourdomain.tld/path/to/file.ext".

Functionality of these methods are nowhere near what you would expect from a URI parser.

@gzog
gzog commented Mar 10, 2015

Was trying to find a solution to track outbound links in a webpage and this gist saved me. :smile:

@barseghyanartur

+1 for solution proposed by @getify

@derdaani

Great one, thanks for sharing.

@daluu
daluu commented May 6, 2015

Nice simple trick. Is there anything as concise as this (w/o addon library) for non-browser based javascript? E.g. node.js, Windows Scripting Host w/ MS JScript, Adobe ExtendScript.

@chasetec

protocol and hostname work in IE with relative URLs if you parser.href = parser.href;

@rogerpadilla

That works great, thanks. Here is the same but with a fallback for non-modern browsers.

var parser;

if (typeof _global.URL === 'function') {
    parser = new _global.URL(path, 'http://example.com');
} else {
    parser = document.createElement('a');
    parser.href = 'http://example.com/' + path;
}
@Demnogonis

What a nifty little trick. Thank you

@rsussland

I know when I encounter some unknown data, my first reaction is to execute it! Genius!! Amazingly simple remote code execution via "javascript:payload"!! No user interaction required!!! Javascript is so cool!!!

@rsussland

And here I am ^^^ being A TOTAL ASS, not reading the code, and not realizing that this doesn't execute javascript, because it's not attached to the DOM. Typing before thinking. Sorry!

@starsea
starsea commented Jul 2, 2015

awesome

@duxiaofeng-github

what a black magic~

@asoashok

HGHG

@tkyeung357

cool!! man

@Folyd
Folyd commented Jan 8, 2016

Thanks a lot. another useful property is a.origin which value is http://example.com :smile:

@natec8
natec8 commented Jan 8, 2016

This is great!

@bluzky
bluzky commented Mar 1, 2016

I didn't think it so simple like this. It's so great.

@civil-popobawa

Dear sirs, how do I parse an url stored in a variable?

@miguelmota

FYI I noticed in Internet Explorer the pathname does not come with the leading slash.

@ASSTAROID

Such As Gnome

@uhtred
uhtred commented Apr 12, 2016

Genius!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.