Flagrant Badassery

A JavaScript and regular expression centric blog

parseUri 1.2: Split URLs in JavaScript

I've just updated parseUri. If you haven't seen the older version, parseUri is a function which splits any well-formed URI into its parts, all of which are optional. Its combination of accuracy, flexibility, and brevity is unrivaled.

Highlights:

  • Comprehensively splits URIs, including splitting the query string into key/value pairs. (Enhanced)
  • Two parsing modes: loose and strict. (New)
  • Easy to use (returns an object, so you can do, e.g., parseUri(uri).anchor).
  • Offers convenient, pre-concatenated components (path = directory and file; authority = userInfo, host, and port; etc.)
  • Change the default names of URI parts without editing the function, by updating parseUri.options.key. (New)
  • Exceptionally lightweight (1 KB before minification or gzipping).
  • Released under the MIT License.

Try the demo, but make sure to come back and read the details below.

Details:

Older versions of this function used what's now called loose parsing mode (which is still the default in this version). Loose mode deviates slightly from the official generic URI spec (RFC 3986), but by doing so allows the function to split URIs in a way that most end users would expect intuitively. However, the finer details of loose mode preclude it from properly handling relative paths which do not start from root (e.g., "../file.html" or "dir/file.html"). On the other hand, strict mode attempts to split URIs according to RFC 3986. Specifically, in loose mode, directories don't need to end with a slash (e.g., the "dir" in "/dir?query" is treated as a directory rather than a file name), and the URI can start with an authority without being preceded by "//" (which means that the "yahoo.com" in "yahoo.com/search/" is treated as the host, rather than part of the directory path).

Since I've assumed that most developers will consistently want to use one mode or the other, the parsing mode is not specified as an argument when running parseUri, but rather as a property of the parseUri function itself. Simply run the following line of code to switch to strict mode:

parseUri.options.strictMode = true;

From that point forward, parseUri will work in strict mode (until you turn it back off).

The code:

// parseUri 1.2.2
// (c) Steven Levithan <stevenlevithan.com>
// MIT License

function parseUri (str) {
	var	o   = parseUri.options,
		m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
		uri = {},
		i   = 14;

	while (i--) uri[o.key[i]] = m[i] || "";

	uri[o.q.name] = {};
	uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
		if ($1) uri[o.q.name][$1] = $2;
	});

	return uri;
};

parseUri.options = {
	strictMode: false,
	key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
	q:   {
		name:   "queryKey",
		parser: /(?:^|&)([^&=]*)=?([^&]*)/g
	},
	parser: {
		strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
		loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
	}
};

You can download it or run the test suite.

parseUri has no dependencies, and has been tested in IE 5.5–7, Firefox 2.0.0.4, Opera 9.21, Safari 3.0.1 beta for Windows, and Swift 0.2.

There Are 161 Responses So Far. »

  1. Nice function. I miss the ability to get the query string as a list of key/value pairs, with a second argument to specify the parameter separator (with the ampersand by default). It’ll make the code a bit longer but the function would become much more complete.

  2. Hi Iván, thanks. parseUri already returns key/value pairs for the query string in an object called queryKey. For example, to access the value of a query key called “search” you could write parseUri(uri).queryKey.search

    You can see this in action on the test page, when you click the Parse button. Does that meet your needs, or were you thinking of something different?

  3. Sorry Steve, I didn’t notice it. That was exactly what I was talking about!
    However, a minor improvement would be to accept as optional second parameter a string which holds in each char a possible argument separator, most people use the ampersand but according to the RFC any char except ‘?’ and ‘#’. See my post http://blog.netxus.es/blog/url-argument-separator

    I use myself the semi-colon ‘;’ as argument separator in some projects, since there is no need to escape it when used in XML/XHTML documents.

  4. Iván, I have no plans to support arbitrary delimiters in the query string because that would significantly complicate the code for the benefit of probably less than 0.1% of developers, and as you noted in your blog post, server side languages like PHP, ASP.net, etc. generally don’t support delimiters other than “&” without special configuration, if at all.

    However, it would be easy to manually change the code to support both “&” and “;” delimiters in your personal copy. Just change /&?([^&=]*)=?([^&]*)/g from within the uri.query.replace() statement to /[&;]?([^&;=]*)=?([^&;]*)/g (or, to support only semicolons, use /;?([^;=]*)=?([^;]*)/g).

    In any case, this does not affect the main URI parsing (only the splitting of the query string into key/value pairs), so you could also implement a separate function to specifically work with the query string with maximum flexibility.

  5. Steve,

    I get your point and quite agree with it. What about placing the query RE in the options object so it can be easily modified by those with especial needs?

  6. wow, that’s one crazy regexp right there…

  7. @Iván Montes,

    Good call. I’ve gone ahead and moved the query regex as well as the query object’s name into the options object and upped the version number from 1.1 to 1.2. Thanks for the suggestion.

  8. [...] parseUri 1.2: Split URLs in JavaScript easy url parsing (tags: code library parsing programming javascript url web webdev uri) [...]

  9. [...] ParseURL на яваскрипте – ParseURL на яваскрипте :) демо [...]

  10. parseUri 1.2: JavaScript URL feldolgozó…

    A php parse_url függvényét már ismerjük. Most ismerjük meg ugyanezt javascripthez is.
    Steven Levithan: parseUri 1.2: Split URLs in JavaScript

    Script:
    /* parseUri 1.2; MIT License
    By Steven Levithan <http://stevenlevithan.com&gt; */

    var pars…

  11. [...] parseUri 1.2: Split URLs in JavaScript (tags: javascript parsing programming opensource) [...]

  12. [...] parseUri 1.2: Split URLs in JavaScript [...]

  13. Hey Steven,

    I couldn’t find any contact info so I’m just leaving a message here. I’m the maintainer of the CFJSON project and I’m trying to fix some things and would benefit from some regexp help and I know you’re quite good with them. If you think you could give me a hand shoot me an email (I put my email in the comment form) and I’ll tell you what I’m trying to fix. Something tells me you’ll be able to solve my problem without too much effort. Thanks in advance.

  14. Thomas, I just sent you an email. I’ll try to help if I can.

  15. [...] parseUri 1.2: Split URLs in JavaScript awesome [...]

  16. Just as a possibility, if you create an anchor, assign the url as href, then you can access the anchor’s host,port,protocol,search,hash. This worked in FF dunno if it will work in the rest. I’m just saying this because it might make your code shorter :)

    I hope it helped

  17. @Ariel Flesler:

    It definitely would not make the code shorter, if you wanted to keep the same functionality as is currently provided. But still, that’s an interesting idea, if it works. ;-)

  18. It looks like it doesn’t support the correct / standard URL parameter delimiter which is actually the ampersand entity ‘&amp;’ not a raw ampersand ‘&’. That’s precisely the functionality I am looking for as I’m getting an annoying error cropping up with one of my scripts that just uses a plain javascript split on ‘&’.

    That said, here are some of the top 10 xhtml errors:
    1. The use of a raw amperstand in a link query string. The w3c validator reports this as “cannot generate system identifier for general entity” because you’ve tried to create a new entity &xxxxxxx and not an encoded & amp ; in the string. Replace all & with &amp; in urls.
    http://elliottback.com/wp/archives/2005/08/14/ten-steps-to-valid-html/

  19. Um, no. This code deals with URIs, not HTML. And of course, &amp; is not the only HTML entity to deal with.

  20. As Safari 2.0 users may have noticed, the ‘queryString’ part isn’t filled because this version does not support a function as second parameter of String.prototype.replace() :-(

  21. I get the following error using your code

    o has no properties

    [Break on this error] m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),

    Please let me know.

    Thanks in advance!
    Neo

  22. @zcrux, does the demo page work for you?

  23. Hey there,

    Is the online demo using the same version of the JS that is available for download?

    I have a URL that will parse in the demo just fine, but returns undefined when doing this: document.write(parseUri(urls).queryKey.q);

    This is the URL btw: http://search.yahoo.com/search?p=flavor+flav&fr=yfp-t-501&toggle=1&cop=mss&ei=UTF-8

  24. @Raj, yes, the demo uses the same code, which you could have easily verified yourself (the source files are uncompressed). Your URL does not contain a q key in the query, so the line of code you posted above is working correctly.

  25. Steven,

    My apologies. Initially, I felt some apprehension about browsing straight to the JS files in the demo. Just being respectful.

    Then I got over it. :)

    Raj

  26. Thank you thank you thank you! In a short few weeks I’ve built at least two functions on top of this little gem and all my pages have components that will depend on them. Such a blessing!

  27. I *love* this function, it is so incredibly powerful and helpful! Thank you so much for it.

    For an open-source project I’m working on, I needed this same functionality inside of a Flash SWF. So, I’ve ported your 1.2.1 code to this regular AS3 function (not an object/class, though that would be easy to get from what I’ve done, too!).

    Since escaping all that reg-ex stuff to post here in the comments would be ridiculous, I’m going to post a URL here that can be used to retrieve a text file with the code in it.

    http://www.flensed.com/parseUri-AS3.txt

    Steven, if want to, grab that text file and place the formatted code somewhere on this page or in this comment, that way people who come here later won’t have to go to my site to find it. :)

  28. @Kyle Simpson and @Hat, thanks! Kyle, I’ll post your AS3 port here for posterity, but there’s no reason people shouldn’t get it from your site!

    //  ****************************
    //  Ported by Kyle Simpson from Javascript to AS3 from:
    //	parseUri 1.2.1
    //	(c) 2007 Steven Levithan <stevenlevithan.com>
    //	MIT License
    //  ****************************
    
    public function parseUri(str:String, strictMode:Boolean=false):Object {
    	var o:Object = new Object();
    	o.strictMode = strictMode;
    	o.key = new Array("source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor");
    	o.q = new Object();
    	o.q.name = "queryKey";
    	o.q.parser = /(?:^|&)([^&=]*)=?([^&]*)/g
    	o.parser = new Object();
    	o.parser.strict = /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/
    	o.parser.loose = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
    
    	var m:Object = o.parser[o.strictMode ? "strict" : "loose"].exec(str);
    	var uri:Object = new Object();
    	var i:int = 14;
    	while (i--) uri[o.key[i]] = m[i] || "";
    	uri[o.q.name] = new Object();
    	uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
    		if ($1) uri[o.q.name][$1] = $2;
    	});
    	return uri;
    }
  29. Big thanks for that amazing function! It helps me a lot with my website programming!

  30. Nice job Steve, very useful… I thought I’d point out a real-world example of a slight problem I saw while using your code, though. For a URL like:

    http://www.zitnay.com/stuff/badurl.php?param=test@test

    it detects everything before the “@” as the userthus screwing up the rest of the parse.

    I realize the “@” should really be URL encoded to “%40″, but like I said, I found a real-world example of this on a live website. So, you might consider adding support for this case, at least in the loose version.

  31. Brilliant! Thanks, this code is powerful yet very friendly allowing non programmers (like myself) to implement it with ease :)

  32. Thanks, nice code!

    I just change the query string parse function. This decode query parameters and distinct ‘key&’ from ‘key=&’: first get ‘true’ as value, last — empty string.

    [code]
    uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2, $3) {
    if ($1) uri[o.q.name][decodeURIComponent($1)] = $2 ? decodeURIComponent($3) : true;
    });
    ...
    parseUri.options = {
    ...
    q: {
    name: "queryKey",
    parser: /(?:^|[&])([^&=]*)(=?)([^&]*)/g
    },
    [/code]

    And small shugar for strings:
    [code]
    // usage: "http://blog.stevenlevithan.com/archives/parseuri".parseUri().

    String.prototype.parseUri = function () { return parseUri(this.valueOf()); };
    [/code]

  33. Hi Steven,

    Just to let you know I have put together a jQuery plugin based on your URI parser, which includes a bit of added functionality.

    You can check it out here – http://projects.allmarkedup.com/jquery_url_parser/

    Let me know if you have any suggestions/improvements etc! And thanks for the excellent work.

  34. Steve,

    I was integrating your parser and noticed that the query parser function is “lossy”. For example, given the query string:

    “a=1&b=2&c=1&c=2&c=3″

    Parsing will result in this query hash: { a: 1, b: 2, c: 3 }

    Here is a rewritten parser function:


    if ($1) {
    if (! b9j.isValue(queryHash[$1])) {
    queryHash[$1] = $2;
    }
    else if (b9j.isArray(queryHash[$1])) {
    queryHash[$1].push($2);
    }
    else {
    queryHash[$1] = [ queryHash[$1], $2 ];
    }
    }

    You can find a full implementation here: http://appengine.bravo9.com/b9j/documentation/uri.html

  35. …oh yeah, and great parser, thanks!

  36. Awesome!!!! kudos Steven for such an elegant program! It served my purpose exactly the way i needed it!

    Thanks again….
    Raju

  37. Hi :)

    I’m new to jQuery and stumbled across your script whilst doing a uni assignment. I’m a bit lost as to how to recover array query strings. ie url?=campus[]=blahland.

    If I do parseUri(location).queryKey.campus%5B%5D it reports a JS error in Firebug.

    Is there a way to strip the [] from the query string so it’ll just be campus?

    Cheers,

    Brendan

  38. I’ve posted an interactive example of my
    JavaScript URI object
    :

    http://appengine.bravo9.com/b9j/example/uri/

  39. @Brendan, what’s an array query string? Assuming the URI you’re feeding this function is actually “url?campus[]=blahland”, you could access the value via parseUri(uri).queryKey["campus[]"]. Them’s JavaScript rules.

    @Robert, good point about e.g. “?c=1&c=2&c=3″. I’ll have to consider how to handle such cases in the next version of this function. Your approach (inserting an array into queryKey) seems pretty reasonable.

  40. [...] After someone suggested a way to match URLs and protocols with wildcards in LockCrypt, I started work implementing a URL which accepted wildcard (*) characters. The result is a class which takes a URL string as a constructor and breaks it apart into it’s component parts. The class is based on a JavaScript regex from Steve Levithan. [...]

  41. [...] parseUri 1.2: Split URLs in JavaScript (tags: javascript parse regex url uri) [...]

  42. Nice script! Could you please add support for domain/subdomain?

  43. Hello Steven,

    We would like to use your excellent code in our project over at
    http://kevin.vanzonneveld.net/techblog/article/phpjs_licensing/

    and in the near future at:
    http://phpjs.org

    We already noticed your code was MIT, but if you would like to be credited differently or have another comment, please drop a line okay?

  44. chrome?

  45. awesome! – nuff said!

  46. Cool script, but I am missing one important function. Function which creates URI back from uri object. My scenario is: parse URI, change URI (query string), write URI back to <a href=”…

  47. Great script! This is working really well for us with one exception. In Safari and Chrome the following URL will not parse:
    (Edit: Long URL removed.)

    I know it’s crazy… It appears to begin working when we limit the length to 450.

    Thanks again for the great script!

  48. @Matt Ruby, I haven’t done any related testing, but the problem may result from the portions of the regexes that deal with user info (user name, password). Those parts can result in a lot of backtracking with long URLs that don’t contain an @ sign, since JavaScript doesn’t have features such as possessive quantifiers, atomic groups, or duplicate subpattern numbers that would help me deal with the backtracking issues.

    If you don’t need support for the user and password properties returned by this script, one easy way to work around the issue is to change the following part of the regex (in both the strict and loose version):

    (?:(([^:@]*):?([^:@]*))?@)?

    To this:

    (?:([^:@]*:[^:@]*|[^:@]*)?@)?

    Then remove the “user” and “password” values from the parseUri.options.key array. If you try this out, please let me know if it solves the issue for you.

  49. @msznapka, on the demo page, if you look at the source, in the demo.js there’s a function called format that does something similar, and may be useful as a starting point for you.

  50. Works like a charm!
    I also changed i = 14; to i = 12;
    and uri[o.key[12]]… to uri[o.key[10]]…

    Thanks for your help!

    -Ruby

  51. @Matt Ruby, cool, thanks for reporting back. After giving this a few more minutes of thought, here’s a way you can get rid of the backtracking problem while keeping the user and password properties around. Replace the pattern I identified earlier (in both the strict and loose regexes) with this:

    (?:(([^:@]*)(?::([^:@]*))?)?@)?

    Everything else should be left the same compared to the original script. When I have some time to more fully review all of parseUri, I’ll include this change in the next version (after the current v1.2.1).

  52. Thanks again! I’ve made your suggested change and things are still working well.

    I look forward to next version.

    -Ruby

  53. I did a PHP port of this amazing function.
    I added 2 features.
    Hope it could be useful !!
    Have fun !

    LudoO

    <?php
    /*
    	PhpParseUri 1.0
    
    	PHP Port of parseUri 1.2.1
    		- added file:///
    		- added : windows drive detection
    		
    	PHP Port: LudoO 2009 <pitaso.com>
    
    	Original JS : (c) 2007 Steven Levithan <stevenlevithan.com>	MIT License
    	
    */
    function parseUri($str) {
    	global $parseUri_options;
    	$o   = $parseUri_options;
    	$r   = $o['parser'][$o['strictMode'] ? "strict" : "loose"];
    	preg_match($r, $str, $m);
    	$uri = array();
    	$i   = 15;
    
    	while ($i--) $uri[$o['key'][$i]] = $m[$i];
    
    	$uri[$o['q']['name']] = array();
    	preg_match_all($o['q']['parser'], $uri[$o['key'][13]], $n);
    	if ($n && sizeof($n)>0){
    		for ($i = 1; $i <= sizeof($n); $i++) {
    			$v =$n[$i];
    			if ($v) $uri[$o['q']['name']][$v[0]] = $v[1];
    		}
    	}
    	return $uri;
    };
    $parseUri_options = array(
    	strictMode => false,
    	key => array("source","protocol","authority","userInfo","user","password","host","port","relative","path","drive","directory","file","query","anchor"),
    	q =>   array(
    		name =>   "queryKey",
    		parser => '/(?:^|&)([^&=]*)=?([^&]*)/'
    	),
    	parser => array(
    		strict => '/^(?:([^:\/?#]+):)?(?:\/\/\/?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?(((?:\/(\w:))?((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/',
    		loose =>  '/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/\/?)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((?:\/(\w:))?(\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/'
    	)
    );
    ?>
    
  54. [...] Javascript does not have a built in method for parsing a url (to get the individual parts that make up a url). Here is a link to a great little function that does all you need, called parseURI. [...]

  55. this function does not work for urls with ipv6 addresses in them

    an example url:
    http://2001:4860:a003::68]/search?q=parseUri+ipv6

  56. Thanks for this! One small issue: if a URL has multiple instances of the same parameter name (as can occur if multiple checkboxes are checked on a form) then queryKey will only contain the last value associated with this name. So if the query string is

    x=a&x=b

    then queryKey.x ends up as ‘b’, and the x=a pair is lost. It might be nicer if, say, an array of strings rather than a single string was assigned to the corresponding element of queryKey in such cases.

  57. Hi Steven,

    Once, i have implemented the URI parser in JavaScript. It looks like the method of String prototype, so you are able to parse input strings in JavaScript-style:

    var url = ‘http://blog.stevenlevithan.com/archives/parseuri’;
    var url_parsed = url.parseUrl();

    The source is located here:
    http://with-love-from-siberia.blogspot.com/2009/07/url-parsing-in-javascript.html

  58. [...] einem keine Lösungen anbietet, um relative Pfade in Absolute zu konvertieren. Es gibt sogar mehrere sehr gute Lösungen. Doch will ich wirklich 100 Zeilen Code schreiben nur um Links zu [...]

  59. I was using your parseUri class in JavaScript and noticed that the path “file.ext” is not considered a file by your script. It looks like it is expecting a preceding slash. I don’t know if this is a bug or just a feature that was left out. My work around was just some extra conditioning tests. Nice work on this class and thanks for posting it.

  60. @Mike, in non-strict mode, a URL starting with a filename (i.e., no preceding slash) is treated as a host, for reasons explained elsewhere. Switch to strict mode and you should be OK.

  61. your code is AWESOME! thanks for your stuff… i stole your dump function too :) ive been looking for something like it for awhile

  62. Great and simple parser. But only one issue I have here – the open social type of url links do not work with your parser, e.g.
    http://blog.stevenlevithan.com/user/@me/folder/@root

  63. [...] Uri-parser [...]

  64. Hi Steven,

    Thanks for the great code! If you’re still maintaining it, here’s an example of a url that has issues:

    http://www.contemporaryartdaily.com/wp-content/uploads/2010/05/4.-AC-2010-InstallShot@Maccarone-NorthGallery-150×150.jpg

  65. @Scott, that URL is invalid. The @ sign is supposed to be URL encoded as “%40″–if you make this change, parseUri will handle it fine.

    FYI, you’re not the first person to request different handling for invalid uses of “@” (see Anup Chatterjee and Andrew Zitnay’s comments here), so perhaps it’s worth looking at changes to “loose” parsing mode, at least, in future versions of this script.

  66. Awesome code. Ultimate Regex.
    I found this letter >a< knocking around, which i present to you for insertion into the appropriate position in your surname.

  67. [...] stevenlevithan?parseUri 1.2: Split URLs in JavaScript?????? [...]

  68. Do you think it’s a bug that jQuery.url.setUrl(“script.js”).attr(“host”) returns script.js?

    PHP’s parse_url, for example, is able to parse that string as the path.

  69. Sorry, strict mode seems to address that, but the jQuery plugin doesn’t seem to use strict mode properly. I will investigate on that end. Thanks for the great parser!

  70. Nice Function. It works 99% of the times..
    I tried it with google search results url as given below and it broke.. query is null!!

    http://www.google.com/#hl=en&source=hp&q=dvd+player&aq=f&aqi=g10&aql=&oq=&gs_rfai=CHmF57nEuTJ-4E5-yMcr6vYgKAAAAqgQFT9CPQHY&fp=7e78d8b98f604090

  71. @James, lol.

    @Neeta, parseUri returns the correct result. Everything after the # sign is the URI fragment (aka anchor). There is no query part.

  72. Dear Mr. Levithan, hello Steven,

    Thanks a lot for your javascript magic.

    I have a feature suggestion if that’s appropriate. Since parseUri is returning an object, would it be a decent idea to add a method which would reassemble the URL back to a string from its parts?

    That could be quite handy for actually manipulating URL’s. One could then alter parts of the URL (add or modify parts of the query, the user information, whatsoever) without doing any regexp magic in their own code.

    Cheers,

    Rien

  73. @Rien,

    there is a source property in the returned object that contains the original string.

    Thanks Steven for this script, I use it together with a Punycode encoder on some proxies to support IDN domains and parseUri has helped a lot keeping the code small.

  74. It break on URL like http://www.blahblah.com/@foo/bar ….

  75. Thank you very much. Your code is awesome.

  76. Very nice! It does break on the URL http://www.blahblah.com/@foo/bar as Leechael noted, but still, for how simple it is, I am duly impressed. My MUCH longer version of a strict RFC-3986 parser written in C is over at github (http://github.com/ajrisi/fsm). I didn’t use regex like you, I used a hand-rolled finite state machine. The output isn’t quite as readable as yours either. Still, might be worth something to someone!

  77. [...] tu z pomoc? przychodzi funkcja parseUri stworzona przez Stevena Levithan. Jej zwi?z?o?? jest wr?cz zadziwiaj?ca. U?ycie jest bardzo proste: wywo?ujemy funkcj? [...]

  78. Actually, the ‘@’ sign is a perfectly valid character for the path, query and fragment portions of a URI according to RFC3986 and does not need to be encoded as ‘%40′.

    Look at the ABNF definition for ‘pchar’ in Appendix A of RFC3986.

  79. @ridgerunner, thanks for the details. I will correct for that in future versions on this script.

  80. Just wanna say: AWESOME WORK!

  81. Hi,

    I’ve taken Robert’s idea of creating an array of values for parameters that were given multiple times. Unlike him, I did so without using a third party library. Here’s the code if anyone’s interested:

    Replace the line

    if ($1) uri[o.q.name][$1] = $2;

    with

    if ($1) {
    if (uri[o.q.name][$1] === undefined) {
    uri[o.q.name][$1] = $2;
    } else if (typeof uri[o.q.name][$1] === ‘[object Array]‘) {
    uri[o.q.name][$1].push($2);
    } else if (typeof uri[o.q.name][$1] === ‘string’) {
    uri[o.q.name][$1] = [ uri[o.q.name][$1], $2];
    }
    }

  82. [...] http://blog.stevenlevithan.com/archives/parseuri var pu = new parseUri(window.location.href); alert(pu.path); ???????????? [...]

  83. [...] I was in need of a way to split a URL into its various parts. To do this in previous versions of ChromeCrawler I used a ready built one I found on the web. [...]

  84. great stuff.
    i just love regexp.
    very cool

  85. Evil corner case >:)
    http://www.test.com/path?__proto__=1

  86. [...] Refer to http://blog.stevenlevithan.com/archives/parseuri [...]

  87. If you need to go the other way (i.e., object spec to URI string), makeUri() can help:

    https://gist.github.com/1073037

  88. javascript absolutize URL : https://gist.github.com/1088850

  89. [...] the??parser functionality is based on the?????regex parser by steven levithan???. [...]

  90. Can you remove the maxlength on the input box? Thanks.

  91. Hello…nice site…http://blog.stevenlevithan.com/archives/parseuri is The Best! Please keep it up webmaster….great job…thumbs up!

  92. Newbie question.
    We have a job application form that uses the document.referrer to identify which job they are applying for. And, I want to add this info into the subject line of the email sent to our hr person. I came across your code that will parse the url.
    how do I take what your parser produces so I can add it to the subject line?

  93. great stuff.
    thanks!

  94. Hi,

    I’ve enhanced the loose mode a bit to support and tokenize literal IPv4 and IPv6 addresses as well as splitting an FQDN into hostname and domain.

    Thanks
    Norbert

    String.prototype.parseUri = function() {
    var o = String.prototype.parseUri.options;
    var m = o.parser.ipv6.exec(this);
    var uri = {};
    var i = 18;
    while (i–)
    uri[o.key[i]] = m[i] || “”;

    uri[o.q.name] = {};
    uri[o.key[16]].replace(o.q.parser, function($0, $1, $2) {
    if ($1)
    uri[o.q.name][$1] = $2;
    });

    if (uri.ipv4 != “”) {
    uri.ip = uri.ipv4;
    }
    else
    if (uri.ipv6 != “”) {
    uri.ip = uri.ipv6;
    }

    return uri;
    };

    String.prototype.parseUri.options = {
    // strictMode : false,
    key : [ "source", "protocol", "authority", "userInfo", "user", "password",
    "host", "ipv4", "ipv6", "basename", "domain", "port", "relative",
    "path", "directory", "file", "query", "anchor" ],
    q : {
    name : “queryKey”,
    parser : /(?:^|&)([^&=]*)=?([^&]*)/g
    },
    parser : {
    ipv6 : /^(?:(?![^:@]+:[^:@\/]*@)([^[:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:(\d+\.\d+\.\d+\.\d+)|\[([a-fA-F0-9:]+)\]|([^.:\/?#]*))(?:\.([^:\/?#]*))?)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
    }
    };

  95. Hi, great piece of code.

    BTW, is there any function for doing the opposite operation? (I mean getting the string URL from the parsed one).

    It could be useful when you need to change some URL params on the query string or any part of the URL. (that’s inded what I need to do on a CMS I’m building: http://code.google.com/p/yupp-cms/)

    Thanks a lot!

  96. Steve,

    I am trying to use your code with server side script in domino xpages. Everything works great except the parameter value returned is a number instead of the correct string. All other values are returned correctly
    Using http://usr:[email protected]:81/dir/dir.2/index.htm?q1=0&&test1&test2=value#top
    uri.queryKey.q1=0
    uri.queryKey.test1=5
    uri.queryKey.test2=11

    Thanks for contributing.

  97. Steve,

    FYI- I used a Domino function to grab from $0 everything to the right of the = sign instead of using $2 and it now returns the correct values. Thanks again for contributing. Great code.

  98. The semicolon at the end of the parseUri function isn’t required as mentioned in section 13 of the spec http://ecma262-5.com/ELS5_HTML.htm#Section_13

  99. Nice post really , Thanks for sharing.

  100. Hi author i would like to ask how could I use this code as javascipt that could display incoming search term to my site. Its like when someone searches in google and arrives to my site, the url of the referrer is parsed and displayed in my website as ” incoming search term (keyword)” ? any suggestion about making it in javascipt?

  101. Hi Steven,

    As some others have pointed out already your code doesn’t work for urls with a @ in the path or query part.

    For example http://www.adperium.com/campaigns/[email protected]/93f92b1c will return example.com as the host.

    According to rfc 3986 section-3.3, @ is a valid path character.

    Since adblock for chrome uses your code to parse urls it currently blocks parts of sites that shouldn’t be blocked.

  102. [...] a look at the parseURI function of Flagrant Badassery’s blog. It can parse any well formed URIs. Tagged: [...]

  103. This was just what I wanted except: I’m passing some javascript code with spaces and funny chars in the string. So I wrote a little extension to decode these:

    So I replaced the line:
    if ($1) uri[o.q.name][$1] = $2
    with
    if ($1) uri[o.q.name][$1] = $2.replace(o.q.decode, function ($3, $4) {
    return ($4) ? String.fromCharCode (parseInt($4, 16)) : ” “;
    });

    and added this to the q structure.
    decode: /(?:\+)|(?:%(..))/g

  104. hello,
    love your work!!!

    found a bug: fail parsing this url
    http://www.test.com/?email=[email protected]

    the problem is the ‘@’ char in queryString value.
    it just destroy it.

  105. @yonathan garti, the easiest way to deal with this is to URL-encode the @ sign as %40. You can see a few people including myself discussing this issue in earlier comments. I plan to correct this in future versions of the script, but haven’t gotten around to it yet. You could try simply changing each instance of [^:@] to [^:@?]. That might do the trick, though I haven’t fully evaluated its impact.

  106. Links like “mailto:[email protected]” are not properly parsed.

  107. [...] parameters, fragment parameters and more. The core parser functionality is based on the Regex URI parser by Steven Levithan, and the query string parsing is handled by a modified version [...]

  108. [...] parametrar, parametrar fragment och mycket mer. Kärnan tolken funktionaliteten bygger på Regex URI parser av Steven Levithan , och frågesträngen parsningen hanteras av en modifierad version av nod-QueryString [...]

  109. it doesn’t work fine if a uri contains “@” character in parameter, just like this:

    http://aaa.bbb.com/index?email=[email protected]

  110. What about data-uri‘s?

  111. I needed to get the file name and extension so I added this before returning the info in the function.

    var file_pieces = uri[o.key[11]].split(‘.’);
    if ( file_pieces.length > 1 )
    {
    uri.file_ext = file_pieces[file_pieces.length - 1];
    file_pieces.splice(file_pieces.length – 1, 1);
    }
    uri.file_name = file_pieces.join(‘.’);

  112. Hi Steven,
    I have tried replacing [^:@] to [^:@?] in both strict and loose mode and i was able to parse the URL containing @ correctly.

    Thanks for the script.

    –Ramesh

  113. this is sweet, i’m focusing on javascript nowadays and your code amazed me, pretty light and effective. thanks!

  114. Hello,

    Sorry but your code break with this valid flickr url: “http://www.flickr.com/photos/9242564@N07/5934435067/”.

    It has problems with “@” char.

  115. What a material of un-ambiguity and preserveness of precious experience on the topic
    of unexpected emotions.

  116. The handling of query strings seems wrong – e.g parse(‘http://example.com/?q=space%20space’).queryKey['q'] will return “space%20space”, not “space space” as it ought to be.

    If you’re turning query keys into a parameter map (rather than leaving them as a raw string), both keys and values should be URI-decoded.

  117. Hi Steven,
    thank you for this very helpful script and putting it under MIT license.
    Please consider removing all the spam comments since August 1.
    Looking forward to the next version of parseUri.
    Regards

  118. I “bowerized” this so that it can be installed via Bower.

    https://github.com/deanapeterson/bower-parseUri

  119. You will fiknd two kinds of interest, fixed rate and variable interest.
    This guarantees they will always have a regular income source.

    The approach includes gifts of life-insurance with gifts to charity.

  120. Habing pr?tein afterwards will aid the recove?y proc?ss.

    This iss actually the perfect spoof to draw us aw?y from tthe clich? pattern regarding
    knight in shining armor slaying dragons annd sorcerers to save his
    love. Maybe in anothwr four ?ecades we’ll be watching s?me future-version of The Today
    Show featuring the kids from Tim Burton’s largely-awful Charlie and The Chocolate Factory.

  121. Use the best website positioning software package to rank to start with on google.
    Maximize your visibility, your rank and your search engine optimization.
    Don’t feel me, test this awesome web optimization computer software for free of charge and see the energy of top quality and
    superior inbound links. Pleased link creating and prepare you to rank bigger and
    receive flood of qualified trafic which really transform.

  122. The a lzrge amount of important business I perfected wwas
    too help choose the best bets wisely. Let this war uniting the casinos
    annd enthusiastic gamers conntinue in support of ever.

  123. Ensure clothes dryers are vented outside the basement, perhaps not inside.
    It is a slimy greenish-black material, which can develop in humikd environments.
    A hiugher degree diabetic person, you’re very prone to attacks.

  124. Usse a clean washcloth to make the surface dry. Also,you will understand what
    methods are suiitable forr you. Fever is alsoo a standard symptom
    of a sensitivity to black mold.

  125. Mold grows in areas of high humidity, warmth, and moisture.
    Also bear in mind that what the companies call a full-size bed isn’t the same as a standard mattress.

  126. An outstanding share! I have just forwarded this onto a co-worker who had been conducting a little homework
    on this. And he in fact ordered me breakfast due to
    the fact that I found it for him… lol. So let me reword this….
    Thank YOU for the meal!! But yeah, thanx for spending time to discuss this topic here on your internet site.

  127. Work wiith a clean washcloth to make the surface dry. Moreover,
    you’ll understand what techniques are ideal for you.
    Temperature can be a typical symptom of an allergy to black mold.

  128. In order a water molecule has 2 atoms of hydrogen and you atom involving oxygen.

    Always shake the bag before shoppers pour your family a mug.

  129. Excess epidermis is a favorite side effect of
    rapid loss in body mass quickly. The experts of this plan suggest you through providing you holistic
    and essential plan. You are lacking to join a fancy gym either.

  130. Both fire damages and water damages are difficult and clear up will be slow.
    The contractor of water damage restoration companies will allow you to get everything out.
    Take any wet books that endd up being in there and layy them out flat to dry.

  131. The establishments deposit liabilities were, however, comparatively temporary.

    You need too pay-off the balances beelow the 30% mark and then preserve them
    below this balance. That is why you’re encouraged not to think, but to utilize.

  132. […] a routine that makes an HTTP request taking a URL as a parameter. It came together nicely. I used a URL parser written by Steven Levithan and the example in the nodejs.org […]

  133. Ensure outfits dryers are vented outside of the basement, perhaps not
    inside. It is a slimy greenish-black material, which may develop in humid environments.
    A top level diabetic person, you’re verey prone to attacks.

  134. You can use Long Path Tool for such issues, it works good.

  135. WOW just what I was searching for. Came here by searching for
    door lock hotel

  136. Locating a great plumber iis really about seeking and then choosing.
    If they do not look just like the class of materials he says he is using, call him on it.

  137. Anaconda is at 5,280 feet – Montana’s mile-high city,flanked mountains, lakes and fields.
    Perhaps you have been struggling since the bubble broke open.

    Solar panels power abilities range from watts to kilowatts.

  138. This makws your future financial planning easy and may
    reduce the strain. Debt settlement is the best option iff you want to dramatically lessen your outstanding
    costs. Singapore can be among the nagions which can be under debt anxiety.

    Nevertheless, treasury bills aren’t a psrt of the plan.

    Study the utmost effective customers of Structured Settlements.

  139. This cause you need to use proper training so available the drivers license.
    A career in this particular industry implies that no two work days are drinks ..

  140. This piece of writing will assist the internet visitors for building up new blog or even a weblog from start to end.

  141. You are so cool! I don’t believe I’ve truly read anything like that before.
    So nice to find somebody with a few unique thoughts on this subject.
    Really.. thank you for starting this up. This
    website is something that is required on the web, someone with a bit of originality!

  142. Home kits are sold in many pharmacy and discount stores.

    Microdermabrasion machine therapies are not difficult to find and are some of the best procedures to market.
    It is just as effective as surgical dermabrasion procedures such as standard dermal abrasion and laser skin resurfacing.

  143. I love your blog.. very nice colors & theme. Did you make this website
    yourself or did you hire someone to do it for you?
    Plz respond as I’m looking to construct my own blog and would like to
    find out where u got this from. thanks a lot

  144. I was suggested this web site by way of my cousin.

    I’m now not positive whether or not this publish is written through
    him as nobody else recognise such detailed about my difficulty.
    You are wonderful! Thank you!

  145. hey all thanks.. very nice your blog . the best your visitor and design

  146. Ron Lewis scored 9 points, going 7 oof 8 in the free-throw line.

    Nonetheless, these foprm of events will noot
    reaqlly direct you towards the college basketball recruiting process.

    There’s clear and indisputable proof of that.

  147. I am really enjoying the theme/design of your
    web site. Do you ever run into any web browser compatibility issues?
    A couple of my blog visitors have complained about my site not working correctly
    in Explorer but looks great in Opera. Do you have any ideas to help fix this issue?

  148. I’m not that much of a internet reader to be honest but your sites really nice, keep it up!
    I’ll go ahead and bookmark your website to come back
    in the future. All the best

  149. Now I am going away to do my breakfast, afterward having my breakfast coming again to read additional news.

  150. I visited various blogs however the audio quality for audio songs existing at this website is actually wonderful.

  151. Just be very cautious when parsing url like the following

    http://example.com/@user123

    you would have expect the host to be example.com, however, the demo give you example of host = user123

  152. The following example causes invalid results:

    http://www.phishinggg.com.g91x.0pz1.com/cgi-bin/webscr/?_dispatch=89a&emaddr=[email protected]&referer=qorp&login-processing=ok

  153. […] used a code snippet from stevenlevithan.com for URL parsing and shortcut.js file from openjs.com for creating keyboard […]

  154. thanks Now I am going away to do my breakfast, afterward having my breakfast coming again to read additional news.

  155. I know this web page offers quality depending articles or reviews and extra stuff, is
    there any other web site which gives these kinds of data
    in quality?

  156. The totally free natural website traffic from search engines like yahoo is a worthwhile asset for any organization that makes use of
    the word wide web. Mso – Normal – Table mso-style-name:”Table Normal”; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:
    0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:
    yes; mso-style-parent:”"; mso-padding-alt:0in 5. Your healthcare web developments have to encompass trust at their heart.

  157. Of course, to get a complete setup you would
    also need the site to be developed. It is
    also helpful to arouse energy and motivate interest.
    In today’s day and age, people are quite passionate about online shopping and are increasingly choosing this option for most of their purchases.

  158. buy chanel Handbags
    I am curious to find out what blog platform you have been utilizing?

    I’m having some small security problems with my latest site and I would like to find something more secure.
    Do you have any recommendations?

  159. Thanks for the marvelous posting! I quite enjoyed reading it, you can be a great author.I will remember to bookmark your blog
    and will eventually come back in the foreseeable future.
    I want to encourage continue your great writing, have a nice evening!

  160. United States chanel
    I love what you guys are usually up too. This kind of clever work and exposure!
    Keep up the good works guys I’ve you guys to blogroll.

  161. Widz?c liczb, uciecha dla dziecku oraz jego efekt.
    Alopecia,hair loss in women,hair growth shampoo.
    Dyspozycja aran?acji gr?, zna w dzi?ki zupe?ny trwanie szkolach a klasach
    przypadkach przenie wszelkich by? mo?e azali? dziecka.
    Szkrab poznawczych latach. sokieba, czyli gnat takie pod?wiadamianie nic bardziej b??dnego zniech?caj?cy ?wiata oraz nauk? ka?dego procesie
    percepcyjno-poznania dowodz?, ?e dwa oczka owo w?asny baza pokojowy i z przyczyny które przy sposobno?ci utrzyma? si? przy
    ?yciu. Zasady gry s? banalnie prostego rachunku, jakim? czasie igraszek czereda w wiele korzy?ci tudzie?
    jego ma?y ch?opiec pierwotnie.

Post a Response

If you are about to post code, please escape your HTML entities (&amp;, &gt;, &lt;).