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
By:
Updated: Jun 5th, 2011
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”)
@William K That still doesn’t work for me
Add a simple check to ignore invalid matches – https://gist.github.com/simonsmith/5152680
?this=1&this=2&this=3
is not covered.
Is there any reason this is stripping out data from my string?
http://example.com/2nd-form-page/?age=87&value=195%2C000&lien=107%2C500&sendbutton=#.UYSKDaKG2So
I am using:
function showAlert() {
var age = queryString[‘age’];
var homeval = queryString[‘value’];
var lien = queryString[‘lien’];
alert(‘The age is ‘ + age + ‘ and value is ‘ + homeval + ‘ and the liens are ‘ + lien + ‘.’);
}
And if the number has a 0, 3, or 8 (from what I can tell so far) the value is cut off. So 70 shows as 7, 100,000 shows as 1, 89 shows as “” (nothing), etc., etc.
Thanks.
Great job and thanks! It has saved me a lot of time. I adjusted it to suit my needs (see below)
// I have altered the function to accept a query string that may have to be parsed to the function
// sample url : “http://shopping.crepidam.com/parts/add_to_cart.php?sku=16030&description=Cylinder%C2%A0Assembly”
function(qryStr){
// this was to fix a problem where the NON Breaking whitespace was not being removed properly and I could not
// get the regex to work where I had multiple instance within the original URL and returned object value
qryStr.replace(‘%C2%A0′,’ ‘);
var queryString = {};
qryStr.replace(
new RegExp(“([^?=&]+)(=([^&#]*))?”, “gi”),
function($0, $1, $2, $3) { queryString[$1] = $3; }
);
}
You can build a string like the example below
// build GET string
var locationStr = “add_to_cart.php?sku=” + queryString[‘sku’] + “&description=” + queryString[‘description’].replace(‘%C2%A0′,’ ‘);
or you can call the object directly as per the original post above
queryString[‘product_id’] and store in a variable for use later
Was write parser for that https://github.com/PxyUp/uri-parse-lib, support nested query and array