Have you ever needed to get query string values using JavaScript? This task is usually a painful split, split, split, iterate, indexOf hack that is really slow and terribly ugly to look at. It also tends to pile up lines of code really fast.
Here is a really sweet way to parse the query string into a JavaScript object with two lines of code using regular expressions to populate an object. I discovered this trick a few years ago and filed it away in my code snippets folder.
The Code
The JavaScript code itself uses the replace() method with a regular expression to target the name/value pairs in the URI string that you are working with. The replace value is actually a function which will be executed for each pair. This little function simply pushes the name/value pair into the queryString object.
var queryString = {};
anchor.href.replace(
new RegExp("([^?=&]+)(=([^&]*))?", "g"),
function($0, $1, $2, $3) { queryString[$1] = $3; }
);
Isn’t it beautiful? In this example anchor is some anchor tag on a page that I have already defined with a document.getElementById. However it works just as well with window.location.href.
Using it
Using this simple trick you can access query string parameters by saying queryString['name']. Let’s say that your URI looks like this:
http://your.domain/product.aspx?category=4&product_id=2140&query=lcd+tv
Want that product ID? Simple, queryString['product_id'] will return “2140″. Nice and simple.
If the query string parameter that you are searching for does not exist then it will return undefined without throwing an error.
Full example
Copy and paste this into your Firebug console and run it to see it in action:
var uri = 'http://your.domain/product.aspx?category=4&product_id=2140&query=lcd+tv';
var queryString = {};
uri.replace(
new RegExp("([^?=&]+)(=([^&]*))?", "g"),
function($0, $1, $2, $3) { queryString[$1] = $3; }
);
console.log('ID: ' + queryString['product_id']); // ID: 2140
console.log('Name: ' + queryString['product_name']); // Name: undefined
console.log('Category: ' + queryString['category']); // Category: 4
Brilliant.
here is another way (converts query string to object):
qso = eval(“({” + location.search.slice(1).replace(/=/g, “:”).replace(/&/g, “,”) + “})”);
For your regex to work with hrefs that include a hash fragment
eg http://mysite.com/here/there.html#now
Change the regex to
new RegExp(“([^?=&]+)(=([^&#]*))?”, “g”),
Simple and well written.
It would be great if you update the article with the change suggested by Scott. :)
Can I use this to pass an item_name to a new web page,… but then to print (document.write?) the item_name *and* provide a link to an image (which is item_name.jpg)? What would the html look like? My brain does not work like a programmers!
Don’t forget window.decodeUriComponent() to handle unescaping.
Nice and simple, I like it. But once you’ve got the queryString object, you don’t have to use the array-style notation, just queryString.product_id will work just fine, making it even cleaner.
I recently had to implement a function similar to this for a jquery plugin. However, my function ended up being quite a bit more complicated, because it also handled nested objects such as:
my[nested][object]=hi //=> {my: {nested: {object: ‘hi’}}}
As well as arrays:
my_array[]=hi&my_array[]=there //=> {my_array: ['hi', 'there']}
…and any combination thereof.
They should include this feature into jQuery, would be so incredibly useful.
Made a jsPerf for it, only difference is I’m using a RegEx literal rather than invoking the RegExp constructor:
http://jsperf.com/query-str-parsing-regex-vs-split
Scott’s eval based parsing has a major risk:
Consider the query string: ?foo=alert(‘oh hai, xss!’)
Before running the query string through that eval, you would have to sanitize it, and by that point, I think you’re better off with Steven’s original regex based solution.
Can’t believe no one has caught this yet. The code above does not work as expected if you pass a URL with no query string. It’ll just return an object containing the URL as key and undefined as value.
To fix, use this regex instead: RegExp(“\\?([^?=&]+)(=([^&#]*))?”, “g”)