Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.

Join them; it only takes a minute:

Sign up
Join the Stack Overflow community to:
  1. Ask programming questions
  2. Answer and help your peers
  3. Get recognized for your expertise

Is there a plugin-less way of retrieving query string values via jQuery (or without)?

If so, how? If not, is there a plugin which can do so?

share

locked by animuson Jul 25 '14 at 19:35

This question's answers are a collaborative effort: if you see something that can be improved, just edit the answer to improve it! No additional answers can be added here

69  
A plain javascript solution without RegEx: css-tricks.com/snippets/javascript/get-url-variables – Lorenzo Polidori Oct 29 '12 at 14:50
6  
Although the top solution to the question deserves its popularity because of its excellent observation that jQuery is not needed, its method of creating new regular expressions and re-parsing the query string for every parameter desired is extremely inefficient. Far more efficient (and versatile) solutions have been in existence for a long time, for example within this article reprinted here: htmlgoodies.com/beyond/javascript/article.php/11877_3755006_3/… – Joseph Myers May 14 '13 at 6:00
1  
possible duplicate of JavaScript query string – Cupcake Jul 31 '13 at 23:09
4  
Joseph, the "excellent observation that jQuery is not needed"? Of course it's not needed. Everything jQuery does, it does using JavaScript. People don't use jQuery because it does stuff that JavaScript can't do. The point of jQuery is convenience. – Vladimir Kornea May 30 '14 at 1:12

73 Answers 73

up vote 4612 down vote accepted

You don't need jQuery for that purpose. You can use just some pure JavaScript:

function getParameterByName(name, url) {
    if (!url) url = window.location.href;
    name = name.replace(/[\[\]]/g, "\\$&");
    var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
}

Usage:

// query string: ?foo=lorem&bar=&baz
var foo = getParameterByName('foo'); // "lorem"
var bar = getParameterByName('bar'); // "" (present with empty value)
var baz = getParameterByName('baz'); // "" (present with no value)
var qux = getParameterByName('qux'); // null (absent)


Note: If a parameter is present several times (?foo=lorem&foo=ipsum), you will get the first value (lorem). There is no standard about this and usages vary, see for example this question: Authoritative position of duplicate HTTP GET query keys.

share
766  
No one's saying it can't be done with pure Javascript. If you're already using jQuery, and jQuery has a function to do this, then it would make sense to use jQuery instead of reinventing the wheel with a new function. – Cerin Jan 31 '11 at 22:05
93  
How does this function handle http://www.mysite.com/index.php?x=x1&x=x2&x=x3 The value of field x is ambiguous. – dpp Jul 9 '11 at 6:34
105  
this doesn't handle parameters that aren't followed by equals sign, which is perfectly legal. for example, ?a=1&b=2&c&d. you'd want to return empty string for c, and undefined for something that isn't there at all (say, e) – Kip Sep 22 '11 at 19:42
54  
this also doesn't handle multi-valued keys, which are also perfectly legal. – hurrymaplelad Oct 7 '11 at 8:47
12  
For a querystring of ?mykey=0&m.+key=1, calling getParameterByName("m.+key") would return 0 instead of 1. You need to escape the regular expression metacharacters in name before building your regular expression. And you only need to call .replace() once by using the global flag and using "\\$&" as the replacement expression. You should search on location.search instead of location.href. An answer with over 400 upvotes should account for these details. – gilly3 Dec 9 '11 at 22:28

Roshambo on snipplr.com has a simple script to achieve this described in Get URL Parameters with jQuery | Improved. With his script you also easily get to pull out just the parameters you want.

Here's the gist:

$.urlParam = function(name, url) {
    if (!url) {
     url = window.location.href;
    }
    var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(url);
    if (!results) { 
        return undefined;
    }
    return results[1] || undefined;
}

Then just get your parameters from the query string.

So if the URL/query string was xyz.com/index.html?lang=de.

Just call var langval = $.urlParam('lang');, and you've got it.

UZBEKJON has a great blog post on this as well, Get URL parameters & values with jQuery.

share
12  
with jQuery seems to mean to namespace the function to the jQuery object. Also, why is the invalid value 0? Sure, I could use strict equality check, but shouldn't it be null ? – alex Jun 17 '12 at 1:34
1  
Exception maybe. Pls no null :( – TFennis Jan 10 '14 at 13:13
1  
check best answer here without regular expression stackoverflow.com/questions/19491336/… – Sameer Kazi Feb 15 at 9:00

Some of the solutions posted here are inefficient. Repeating the regular expression search every time the script needs to access a parameter is completely unnecessary, one single function to split up the parameters into an associative-array style object is enough. If you're not working with the HTML 5 History API, this is only necessary once per page load. The other suggestions here also fail to decode the URL correctly.

var urlParams;
(window.onpopstate = function () {
    var match,
        pl     = /\+/g,  // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
        query  = window.location.search.substring(1);

    urlParams = {};
    while (match = search.exec(query))
       urlParams[decode(match[1])] = decode(match[2]);
})();

Example querystring:

?i=main&mode=front&sid=de8d49b78a85a322c4155015fdce22c4&enc=+Hello%20&empty

Result:

 urlParams = {
    enc: " Hello ",
    i: "main",
    mode: "front",
    sid: "de8d49b78a85a322c4155015fdce22c4",
    empty: ""
}

alert(urlParams["mode"]);
// -> "front"

alert("empty" in urlParams);
// -> true

This could easily be improved upon to handle array-style query strings too. An example of this is here, but since array-style parameters aren't defined in RFC 3986 I won't pollute this answer with the source code. For those interested in a "polluted" version, look at campbeln's answer below.

Also, as pointed out in the comments, ; is a legal delimiter for key=value pairs. It would require a more complicated regex to handle ; or &, which I think is unnecessary because it's rare that ; is used and I would say even more unlikely that both would be used. If you need to support ; instead of &, just swap them in the regex.


If you're using a server-side preprocessing language, you might want to use its native JSON functions to do the heavy lifting for you. For example, in PHP you can write:

<script>var urlParams = <?php echo json_encode($_GET, JSON_HEX_TAG);?>;</script>

Much simpler!

share
8  
if you're doing a heavily ajax'd app, then you may be using the hash(#) to "enable the back button"... in that case the querystring would change all the time (see how facebook does it)... though these solutions ignore things that come after the # anways... – Nick Franceschina Jul 14 '10 at 0:12
88  
@Nick: Anything after the hash resides in the window.location.hash property, which is separate from the window.location.search property. If the hash changes, it doesn't affect the querystring at all. – Andy E Jul 14 '10 at 9:20
21  
Don't forget the ; is a legal delimiter for GET key=value pairs. It is rare, but it takes 5 seconds to implement. – alex Nov 15 '10 at 11:26
22  
-1 for creating an XSS vulnerability by using json_encode without JSON_HEX_TAG. – qerub Feb 15 '12 at 15:15
13  
For those of us using a fairly strict setup of JSHint swap the while(match = search.exec(query)) with while((match = search.exec(query)) !== null) – craigts Sep 4 '13 at 19:26

Roshambo jQuery method wasn't taking care of decode URL

http://snipplr.com/view/26662/get-url-parameters-with-jquery--improved/

Just added that capability also while adding in the return statement

return decodeURIComponent(results[1].replace(/\+/g, " ")) || 0;

Now you can find the updated gist:

$.urlParam = function(name){
var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
if (!results) { return 0; }
return decodeURIComponent(results[1].replace(/\+/g, " ")) || 0;
}
share

I like this one (taken from jquery-howto.blogspot.co.uk):

// get an array with all querystring values
// example: var valor = getUrlVars()["valor"];
function getUrlVars() {
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for (var i = 0; i < hashes.length; i++) {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars;
}

Works great for me.

share

The problem with top answer on that question is that it's not support params placed after #, but sometimes it's needed to get this value also. I modify the unswer to let it parse full query string with hash sign also

var getQueryStringData = function(name) {
    var result = null;
    var regexS = "[\\?&#]" + name + "=([^&#]*)";
    var regex = new RegExp(regexS);
    var results = regex.exec('?' + window.location.href.split('?')[1]);
    if (results != null) {
        result = decodeURIComponent(results[1].replace(/\+/g, " "));
    }
    return result;
};
share
1  
That's interesting if you need it but there's no standard for the format of the hash part AFAIK so it's not fair to call that out as a weakness of the other answer. – Rup Apr 22 '13 at 12:48
2  
Yes, I know. But in my app i integrate 3rd party js navigation, which have some parameters after hash sign. – Ph0en1x Apr 22 '13 at 14:15

This is a function I created a while back and I'm quite happy with. It is not case sensitive - which is handy. Also, if the requested QS doesn't exist, it just returns an empty string.

I use a compressed version of this. I'm posting uncompressed for the novice types to better explain what's going on.

I'm sure this could be optimized or done differently to work faster, but it's always worked great for what I need.

Enjoy.

function getQSP(sName, sURL) {
    var theItmToRtn = "";
    var theSrchStrg = location.search;
    if (sURL) theSrchStrg = sURL;
    var sOrig = theSrchStrg;
    theSrchStrg = theSrchStrg.toUpperCase();
    sName = sName.toUpperCase();
    theSrchStrg = theSrchStrg.replace("?", "&") theSrchStrg = theSrchStrg + "&";
    var theSrchToken = "&" + sName + "=";
    if (theSrchStrg.indexOf(theSrchToken) != -1) {
        var theSrchTokenLth = theSrchToken.length;
        var theSrchTokenLocStart = theSrchStrg.indexOf(theSrchToken) + theSrchTokenLth;
        var theLocOfNextAndSign = theSrchStrg.indexOf("&", theSrchTokenLocStart);
        theItmToRtn = unescape(sOrig.substring(theSrchTokenLocStart, theLocOfNextAndSign));
    }
    return unescape(theItmToRtn);
}
share
26  
you need to work on those var names – ajax333221 May 25 '12 at 22:20

tl;dr

A quick, complete solution, which handles multivalued keys and encoded characters.

var qd = {};
location.search.substr(1).split("&").forEach(function(item) {var s = item.split("="), k = s[0], v = s[1] && decodeURIComponent(s[1]); (k in qd) ? qd[k].push(v) : qd[k] = [v]})
multi-lined:
var qd = {};
location.search.substr(1).split("&").forEach(function(item) {
    var s = item.split("="),
        k = s[0],
        v = s[1] && decodeURIComponent(s[1]);
    (k in qd) ? qd[k].push(v) : qd[k] = [v]
})
example:
"?a=1&b=0&c=3&d&e&a=5&a=t%20e%20x%20t&e=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dståle%26car%3Dsaab"
> qd
a: ["1", "5", "t e x t"]
b: ["0"]
c: ["3"]
d: [undefined]
e: [undefined, "http://w3schools.com/my test.asp?name=ståle&car=saab"] 

> qd.a[1]    // "5"
> qd["a"][1] // "5" 

Read more... about the vanilla JavaScript solution

To access different parts of url use location.(search|hash)

easiest (dummy) solution

var queryDict = {};
location.search.substr(1).split("&").forEach(function(item) {queryDict[item.split("=")[0]] = item.split("=")[1]})
  • Handles empty keys correctly.
  • Overrides multi-keys with last value found.
"?a=1&b=0&c=3&d&e&a=5"
> queryDict
a: "5"
b: "0"
c: "3"
d: undefined
e: undefined

multi-valued keys

Simple key check (item in dict) ? dict.item.push(val) : dict.item = [val]

var qd = {};
location.search.substr(1).split("&").forEach(function(item) {(item.split("=")[0] in qd) ? qd[item.split("=")[0]].push(item.split("=")[1]) : qd[item.split("=")[0]] = [item.split("=")[1]]})
  • Now returns arrays instead.
  • Access values by qd.key[index] or qd[key][index]
> qd
a: ["1", "5"]
b: ["0"]
c: ["3"]
d: [undefined]
e: [undefined]

encoded characters?

Use decodeURIComponent() for the second or both splits.

var qd = {};
location.search.substr(1).split("&").forEach(function(item) {var k = item.split("=")[0], v = decodeURIComponent(item.split("=")[1]); (k in qd) ? qd[k].push(v) : qd[k] = [v]})
example:
"?a=1&b=0&c=3&d&e&a=5&a=t%20e%20x%20t&e=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dståle%26car%3Dsaab"
> qd
a: ["1", "5", "t e x t"]
b: ["0"]
c: ["3"]
d: ["undefined"]  // decodeURIComponent(undefined) returns "undefined" !!!*
e: ["undefined", "http://w3schools.com/my test.asp?name=ståle&car=saab"]

*!!! Please note, that decodeURIComponent(undefined) returns string "undefined". The solution lies in a simple usage of &&, which ensures that decodeURIComponent() is not called on undefined values. (See the "complete solution" at the top.)

v = v && decodeURIComponent(v);
share
1  
@PavelNikolov I think it would introduce difficulties getting sometimes an array and sometimes a value. You would have to check for it first, now you only check the length, because you will be using cycles for retrieving those values anyways. Also this was meant to be the easiest, but functional, solution here. – Qwerty Jan 16 '14 at 21:20
1  
Flattened out a bit for readability, made into a function, and re-used split call: function parseQueryString() { var qd = {}; location.search.substr(1).split("&").forEach(function(item) { var parts = item.split("="); var k = parts[0]; var v = decodeURIComponent(parts[1]); (k in qd) ? qd[k].push(v) : qd[k] = [v,] }); return qd; } – Casey Feb 6 '15 at 10:04
1  
decodeDocumentURI(undefined) returns "undefined" instead of undefined. A functional but not very elegant patch: var qd = {}; location.search.substr(1).split("&").forEach( function(item) { var s = item.split("="), k = s[0], v; if(s.length>1) v = decodeURIComponent(s[1]); (k in qd) ? qd[k].push(v) : qd[k] = [v] }) – loop Jun 24 '15 at 12:07

Use the following to get a query param value given a key name:

function getParam(key) 
  {
  // Find the key and everything up to the ampersand delimiter
  var value=RegExp(""+key+"[^&]+").exec(window.location.search);

  // Return the unescaped value minus everything starting from the equals sign or an empty string
  return unescape(!!value ? value.toString().replace(/^[^=]+./,"") : "");
  }

Use a stronger regex if you have a common substring problem:

function getParamNamed(key) 
  {
  // Find the key and everything up to the ampersand delimiter
  // Make sure key is the full name, not a substring
  var value=RegExp("[?&]"+key+"=[^&]+").exec(window.location.search);

  // Return the unescaped value minus everything starting from the equals sign or an empty string
  return unescape(!!value ? value.toString().replace(/^[^=]+./,"") : "");
  }

Firefox supports the URLSearchParams API. It is not standardized by W3C, but is a living standard by WhatWG.

share

Here is a fast way to get an object similar to the PHP $_GET array:

function get_query(){
    var url = location.search;
    var qs = url.substring(url.indexOf('?') + 1).split('&');
    for(var i = 0, result = {}; i < qs.length; i++){
        qs[i] = qs[i].split('=');
        result[qs[i][0]] = decodeURIComponent(qs[i][1]);
    }
    return result;
}

Usage:

var $_GET = get_query();

For the query string x=5&y&z=hello&x=6 this returns the object:

{
  x: "6",
  y: undefined,
  z: "hello"
}
share
1  
Not working if you have hashes. For example: test.aspx?test=t1#default. Will return { test: "t1#default" } and I expect {test : "t1" } – Bogdan M. Jan 16 '14 at 8:52

From the MDN:

function loadPageVar (sVar) {
  return unescape(window.location.search.replace(new RegExp("^(?:.*[&\\?]" + escape(sVar).replace(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1"));
}

alert(loadPageVar("name"));
share

Amazing how many overly complicated and incomplete solutions are posted here. Here's what I'm using:

/**
 * Returns a bare object of the URL's query parameters.
 * You can pass just a query string rather than a complete URL.
 * The default URL is the current page.
 */
function getUrlParams (url) {
    // http://stackoverflow.com/a/23946023/2407309
    if (typeof url == 'undefined') {
        url = window.location.search
    }
    var url = url.split('#')[0] // Discard fragment identifier.
    var queryString = url.split('?')[1]
    if (!queryString) {
        if (url.search('=') !== false) {
            queryString = url
        }
    }
    var urlParams = {}
    if (queryString) {
        var keyValuePairs = queryString.split('&')
        for (var i = 0; i < keyValuePairs.length; i++) {
            var keyValuePair = keyValuePairs[i].split('=')
            var paramName = keyValuePair[0]
            var paramValue = keyValuePair[1] || ''
            urlParams[paramName] = decodeURIComponent(paramValue.replace(/\+/g, ' '))
        }
    }
    return urlParams
} // getUrlParams

Works with following URLs (values of getUrlParams()['test'] in parens):

example.com                         (undefined)
example.com?                        (undefined)
example.com?test                    (empty string)
example.com?test=                   (empty string)
example.com?test=0                  (the string '0')
example.com?test=0&test=override    (the string 'override')

Returning 'override' rather than '0' in the last case makes it consistent with PHP. Works in IE7.

share
1  
Why not? HTML 5 doesn't restrict the character set for input control names, nor is there any guarantee that they come from HTML anyway. I can't see why there would be a restriction to printable characters. – Rup Nov 18 '14 at 12:09
6  
'Amazing how many overly complicated and incomplete solutions are posted here' Lol, the irony.. – NiCk Newman Jul 13 '15 at 16:14

Here's an extended version of Andy E's linked "Handle array-style query strings"-version. Fixed a bug (?key=1&key[]=2&key[]=3; 1 is lost and replaced with [2,3]), made a few minor performance improvements (re-decoding of values, recalculating "[" position, etc.) and added a number of improvements (functionalized, support for ?key=1&key=2, support for ; delimiters). I left the variables annoyingly short, but added comments galore to make them readable (oh, and I reused v within the local functions, sorry if that is confusing ;).

It will handle the following querystring...

?test=Hello&person=neek&person[]=jeff&person[]=jim&person[extra]=john&test3&nocache=1398914891264

...making it into an object that looks like...

{
    "test": "Hello",
    "person": {
        "0": "neek",
        "1": "jeff",
        "2": "jim",
        "length": 3,
        "extra": "john"
    },
    "test3": "",
    "nocache": "1398914891264"
}

As you can see above, this version handles some measure of "malformed" arrays, i.e. - person=neek&person[]=jeff&person[]=jim or person=neek&person=jeff&person=jim as the key is identifiable and valid (at least in dotNet's NameValueCollection.Add):

If the specified key already exists in the target NameValueCollection instance, the specified value is added to the existing comma-separated list of values in the form "value1,value2,value3".

It seems the jury is somewhat out on repeated keys as there is no spec. In this case, multiple keys are stored as an (fake)array. But do note that I do not process values based on commas into arrays.

The code:

getQueryStringKey = function(key) {
    return getQueryStringAsObject()[key];
};


getQueryStringAsObject = function() {
    var b, cv, e, k, ma, sk, v, r = {},
        d = function (v) { return decodeURIComponent(v).replace(/\+/g, " "); }, //# d(ecode) the v(alue)
        q = window.location.search.substring(1),
        s = /([^&;=]+)=?([^&;]*)/g //# original regex that does not allow for ; as a delimiter:   /([^&=]+)=?([^&]*)/g
    ;

    //# ma(make array) out of the v(alue)
    ma = function(v) {
        //# If the passed v(alue) hasn't been setup as an object
        if (typeof v != "object") {
            //# Grab the cv(current value) then setup the v(alue) as an object
            cv = v;
            v = {};
            v.length = 0;

            //# If there was a cv(current value), .push it into the new v(alue)'s array
            //#     NOTE: This may or may not be 100% logical to do... but it's better than loosing the original value
            if (cv) { Array.prototype.push.call(v, cv); }
        }
        return v;
    };

    //# While we still have key-value e(ntries) from the q(uerystring) via the s(earch regex)...
    while (e = s.exec(q)) { //# while((e = s.exec(q)) !== null) {
        //# Collect the open b(racket) location (if any) then set the d(ecoded) v(alue) from the above split key-value e(ntry) 
        b = e[1].indexOf("[");
        v = d(e[2]);

        //# As long as this is NOT a hash[]-style key-value e(ntry)
        if (b < 0) { //# b == "-1"
            //# d(ecode) the simple k(ey)
            k = d(e[1]);

            //# If the k(ey) already exists
            if (r[k]) {
                //# ma(make array) out of the k(ey) then .push the v(alue) into the k(ey)'s array in the r(eturn value)
                r[k] = ma(r[k]);
                Array.prototype.push.call(r[k], v);
            }
            //# Else this is a new k(ey), so just add the k(ey)/v(alue) into the r(eturn value)
            else {
                r[k] = v;
            }
        }
        //# Else we've got ourselves a hash[]-style key-value e(ntry) 
        else {
            //# Collect the d(ecoded) k(ey) and the d(ecoded) sk(sub-key) based on the b(racket) locations
            k = d(e[1].slice(0, b));
            sk = d(e[1].slice(b + 1, e[1].indexOf("]", b)));

            //# ma(make array) out of the k(ey) 
            r[k] = ma(r[k]);

            //# If we have a sk(sub-key), plug the v(alue) into it
            if (sk) { r[k][sk] = v; }
            //# Else .push the v(alue) into the k(ey)'s array
            else { Array.prototype.push.call(r[k], v); }
        }
    }

    //# Return the r(eturn value)
    return r;
};
share
  $(document).ready(function () {
      var urlParams = {};
      (function () {
          var match,
          pl = /\+/g, // Regex for replacing addition symbol with a space
              search = /([^&=]+)=?([^&]*)/g,
              decode = function (s) {
                  return decodeURIComponent(s.replace(pl, " "));
              },
              query = window.location.search.substring(1);

          while (match = search.exec(query))
          urlParams[decode(match[1])] = decode(match[2]);
      })();
      if (urlParams["q1"] === 1) {
          return 1;
      }

Please check and let me know your comments. Also Refer: How to get querystring value using jQuery

share
2  
@Rup : I have got this from codeproject.com/Tips/529496/Handling-QueryString-Using-jQuery – Pushkraj Jul 23 '13 at 13:14

If you are using Browserify, you can use the url module from Node.js:

var url = require('url');

url.parse('http://example.com/?bob=123', true).query;

// returns { "bob": "123" }

Further reading: URL Node.js v0.12.2 Manual & Documentation

share
3  
As the question mentions jQuery, I would assume this is in the browser. – Luca Spiller May 16 '13 at 9:31
// Parse query string
var params = {}, queryString = location.hash.substring(1),
    regex = /([^&=]+)=([^&]*)/g,
    m;
while (m = regex.exec(queryString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
}
share

Doing this reliably is more involved than one may think at first.

  1. location.search, which is used in other answers, is brittle and should be avoided - for example, it returns empty if someone screws up and puts a #fragment identifier before the ?query string.
  2. There are a number of ways URLs get automatically escaped in the browser, which makes decodeURIComponent pretty much mandatory, in my opinion.
  3. Many query strings are generated from user input, which means assumptions about the URL content are very bad. Including very basic things like that each key is unique or even has a value.

To solve this, here is a configurable API with a healthy dose of defensive programming. Note that it can be made half the size if you are willing to hardcode some of the variables, or if the input can never include hasOwnProperty, etc.

Version 1: Returns a data object with names and values for each parameter. It effectively de-duplicates them and always respects the first one found from left-to-right.

function getQueryData(url, paramKey, pairKey, missingValue, decode) {

    var query, queryStart, fragStart, pairKeyStart, i, len, name, value, result;

    if (!url || typeof url !== 'string') {
        url = location.href; // more robust than location.search, which is flaky
    }
    if (!paramKey || typeof paramKey !== 'string') {
        paramKey = '&';
    }
    if (!pairKey || typeof pairKey !== 'string') {
        pairKey = '=';
    }
    // when you do not explicitly tell the API...
    if (arguments.length < 5) {
        // it will unescape parameter keys and values by default...
        decode = true;
    }

    queryStart = url.indexOf('?');
    if (queryStart >= 0) {
        // grab everything after the very first ? question mark...
        query = url.substring(queryStart + 1);
    } else {
        // assume the input is already parameter data...
        query = url;
    }
    // remove fragment identifiers...
    fragStart = query.indexOf('#');
    if (fragStart >= 0) {
        // remove everything after the first # hash mark...
        query = query.substring(0, fragStart);
    }
    // make sure at this point we have enough material to do something useful...
    if (query.indexOf(paramKey) >= 0 || query.indexOf(pairKey) >= 0) {
        // we no longer need the whole query, so get the parameters...
        query = query.split(paramKey);
        result = {};
        // loop through the parameters...
        for (i = 0, len = query.length; i < len; i = i + 1) {
            pairKeyStart = query[i].indexOf(pairKey);
            if (pairKeyStart >= 0) {
                name = query[i].substring(0, pairKeyStart);
            } else {
                name = query[i];
            }
            // only continue for non-empty names that we have not seen before...
            if (name && !Object.prototype.hasOwnProperty.call(result, name)) {
                if (decode) {
                    // unescape characters with special meaning like ? and #
                    name = decodeURIComponent(name);
                }
                if (pairKeyStart >= 0) {
                    value = query[i].substring(pairKeyStart + 1);
                    if (value) {
                        if (decode) {
                            value = decodeURIComponent(value);
                        }
                    } else {
                        value = missingValue;
                    }
                } else {
                    value = missingValue;
                }
                result[name] = value;
            }
        }
        return result;
    }
}

Version 2: Returns a data map object with two identical length arrays, one for names and one for values, with an index for each parameter. This one supports duplicate names and intentionally does not de-duplicate them, because that is probably why you would want to use this format.

function getQueryData(url, paramKey, pairKey, missingValue, decode) {

   var query, queryStart, fragStart, pairKeyStart, i, len, name, value, result;

   if (!url || typeof url !== 'string') {
       url = location.href; // more robust than location.search, which is flaky
   }
   if (!paramKey || typeof paramKey !== 'string') {
       paramKey = '&';
   }
   if (!pairKey || typeof pairKey !== 'string') {
       pairKey = '=';
   }
   // when you do not explicitly tell the API...
   if (arguments.length < 5) {
       // it will unescape parameter keys and values by default...
       decode = true;
   }

   queryStart = url.indexOf('?');
   if (queryStart >= 0) {
       // grab everything after the very first ? question mark...
       query = url.substring(queryStart + 1);
   } else {
       // assume the input is already parameter data...
       query = url;
   }
   // remove fragment identifiers...
   fragStart = query.indexOf('#');
   if (fragStart >= 0) {
       // remove everything after the first # hash mark...
       query = query.substring(0, fragStart);
   }
   // make sure at this point we have enough material to do something useful...
   if (query.indexOf(paramKey) >= 0 || query.indexOf(pairKey) >= 0) {
       // we no longer need the whole query, so get the parameters...
       query = query.split(paramKey);
       result = {
           names: [],
           values: []
       };
       // loop through the parameters...
       for (i = 0, len = query.length; i < len; i = i + 1) {
           pairKeyStart = query[i].indexOf(pairKey);
           if (pairKeyStart >= 0) {
               name = query[i].substring(0, pairKeyStart);
           } else {
               name = query[i];
           }
           // only continue for non-empty names...
           if (name) {
               if (decode) {
                   // unescape characters with special meaning like ? and #
                   name = decodeURIComponent(name);
               }
               if (pairKeyStart >= 0) {
                   value = query[i].substring(pairKeyStart + 1);
                   if (value) {
                       if (decode) {
                           value = decodeURIComponent(value);
                       }
                   } else {
                       value = missingValue;
                   }
               } else {
                   value = missingValue;
               }
               result.names.push(name);
               result.values.push(value);
           }
       }
       return result;
   }

}

share
2  
Neat, though the majority of answers here deal with splitting up the query part into parameters rather than extracting it from an arbitrary URL. Most of them assume we're on the current page and so just use location.search to get the string you're extracting. – Rup Jan 17 '14 at 10:01
1  
I took the very short and vague question to mean something very different than what everyone else did. It's now obvious to me what was meant, and I have updated my answer to include a significantly better design that is on par. – Seth Holladay Oct 11 '14 at 3:02

If you're using jQuery, you can use a library, such as jQuery BBQ: Back Button & Query Library.

...jQuery BBQ provides a full .deparam() method, along with both hash state management, and fragment / query string parse and merge utility methods.

Edit: Adding Deparam Example:

 var DeparamExample = function() {
            var params = $.deparam.querystring();

            //nameofparam is the name of a param from url
            //code below will get param if ajax refresh with hash
            if (typeof params.nameofparam == 'undefined') {
                params = jQuery.deparam.fragment(window.location.href);
            }
            
            if (typeof params.nameofparam != 'undefined') {
                var paramValue = params.nameofparam.toString();
                  
            }
        };

If you want to just use plain JavaScript, you could use...

var getParamValue = (function() {
    var params;
    var resetParams = function() {
            var query = window.location.search;
            var regex = /[?&;](.+?)=([^&;]+)/g;
            var match;

            params = {};

            if (query) {
                while (match = regex.exec(query)) {
                    params[match[1]] = decodeURIComponent(match[2]);
                }
            }    
        };

    window.addEventListener
    && window.addEventListener('popstate', resetParams);

    resetParams();

    return function(param) {
        return params.hasOwnProperty(param) ? params[param] : null;
    }

})();​

Because of the new HTML History API and specifically history.pushState() and history.replaceState(), the URL can change which will invalidate the cache of parameters and their values.

This version will update its internal cache of parameters each time the history changes.

share

This didn't work for me, I want to match `?b' as the 'b' parameter is present, and not match '?return' as the 'r' parameter, here is my solution.

window.query_param = function(name) {
  var param_value, params;

  params = location.search.replace(/^\?/, '');
  params = _.map(params.split('&'), function(s) {
    return s.split('=');
  });

  param_value = _.select(params, function(s) {
    return s.first === name;
  })[0];

  if (param_value) {
    return decodeURIComponent(param_value[1] || '');
  } else {
    return null;
  }
};
share

Without jQuery

var qs = (function(a) {
    if (a == "") return {};
    var b = {};
    for (var i = 0; i < a.length; ++i)
    {
        var p=a[i].split('=', 2);
        if (p.length == 1)
            b[p[0]] = "";
        else
            b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
    }
    return b;
})(window.location.search.substr(1).split('&'));

With an URL like ?topic=123&name=query+string, the following will return:

qs["topic"];    // 123
qs["name"];     // query string
qs["nothere"];  // undefined (object)

Google method

Tearing Google's code I found the method they use: getUrlParameters

function (b) {
    var c = typeof b === "undefined";
    if (a !== h && c) return a;
    for (var d = {}, b = b || k[B][vb], e = b[p]("?"), f = b[p]("#"), b = (f === -1 ? b[Ya](e + 1) : [b[Ya](e + 1, f - e - 1), "&", b[Ya](f + 1)][K](""))[z]("&"), e = i.dd ? ia : unescape, f = 0, g = b[w]; f < g; ++f) {
        var l = b[f][p]("=");
        if (l !== -1) {
            var q = b[f][I](0, l),
                l = b[f][I](l + 1),
                l = l[Ca](/\+/g, " ");
            try {
                d[q] = e(l)
            } catch (A) {}
        }
    }
    c && (a = d);
    return d
}

It is obfuscated, but it is understandable.

They start to look for parameters on the url from ? and also from the hash #. Then for each parameter they split in the equal sign b[f][p]("=") (which looks like indexOf, they use the position of the char to get the key/value). Having it split they check whether the parameter has a value or not, if it has they store the value of d, if not it just continue.

In the end the object d is returned, handling escaping and the + sign. This object is just like mine, it has the same behavior.


My method as a jQuery plugin

(function($) {
    $.QueryString = (function(a) {
        if (a == "") return {};
        var b = {};
        for (var i = 0; i < a.length; ++i)
        {
            var p=a[i].split('=');
            if (p.length != 2) continue;
            b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
        }
        return b;
    })(window.location.search.substr(1).split('&'))
})(jQuery);

Usage

$.QueryString["param"]

Performance test (split method against regex method) (jsPerf)

Preparation code: methods declaration

Split test code

var qs = window.GetQueryString(query);

var search = qs["q"];
var value = qs["value"];
var undef = qs["undefinedstring"];

Regex test code

var search = window.getParameterByName("q");
var value = window.getParameterByName("value");
var undef = window.getParameterByName("undefinedstring");

Testing in Firefox 4.0 x86 on Windows Server 2008 R2 / 7 x64

  • Split method: 144,780 ±2.17% fastest
  • Regex method: 13,891 ±0.85% | 90% slower
share
6  
@Andy: I've posted an improved version. What do you think of it? – BrunoLM Oct 16 '10 at 1:51
31  
Curious why you'd make this a jQuery plugin when it doesn't have any jQuery specific code? – zachleat Feb 23 '11 at 13:55
36  
@zachleat if you don't have a framework your functions will just get spread across your code. If you extend jQuery you will have a scope for your functions, it won't be floating around somewhere in your code. I think that is the only reason. – BrunoLM Feb 23 '11 at 13:57
5  
Here is the jQuery version tweaked to pass JSLint (at least the semi-moving target of JSLint.com on 2011-06-15). Mostly just moving things around to appease The Crockford. – patridge Jun 15 '11 at 17:48
5  
Thank god for the benchmark. I'm writing code that needs to access a 50 thousand query string parameters and now I know which one to use. – Benjamin Gruenbaum Sep 7 '13 at 15:41

Just another recommendation. The plugin Purl allows to retrieve all parts of URL, including anchor, host, etc.

It can be used with or without jQuery.

Usage is very simple and cool:

var url = $.url('http://allmarkedup.com/folder/dir/index.html?item=value'); // jQuery version
var url = purl('http://allmarkedup.com/folder/dir/index.html?item=value'); // plain JS version
url.attr('protocol'); // returns 'http'
url.attr('path'); // returns '/folder/dir/index.html'
share
3  
This URL parser is ridiculously fat in file size.. – vsync Jan 21 '14 at 14:25
10  
URL parsing isn't simple. – dimadima Mar 1 '14 at 4:17
2  
Seeing the RegEx engine for purl was created by RegEx Genius Steve Levithan... I'm gonna use this. – Eddie B Sep 2 '14 at 23:57
5  
As of writing purl is no longer maintained and the previous maintainer suggests uri.js – Dan Pantry Mar 26 '15 at 12:49

This function will return a parsed JavaScript object with any arbitrarily nested values using recursion as necessary.

Here's a jsfiddle example.

[
  'a=a',
  '&b=a',
  '&b=b',
  '&c[]=a',
  '&c[]=b',
  '&d[a]=a',
  '&d[a]=x',
  '&e[a][]=a',
  '&e[a][]=b',
  '&f[a][b]=a',
  '&f[a][b]=x',
  '&g[a][b][]=a',
  '&g[a][b][]=b',
  '&h=%2B+%25'
].join('');

Given any of the above test examples.

ls = function() {
  var a, b, c, e;
  a = {};
  b = window.location.search.substring(1);
  c = function(d) {
    return d && decodeURIComponent(d.replace(/\+/g, ' '));
  };
  e = function(f, g, h) {
    var i, j, k, l;
    i = g.indexOf('[');
    if (i !== -1) {
      j = g.slice(0, i);
      k = g.slice(1 + i).slice(0, g.slice(1 + i).indexOf(']'));
      l = g.slice(1 + i).slice(1 + g.slice(1 + i).indexOf(']'));
      if (k) {
        if (typeof f[j] !== 'object') {
          f[j] = {};
        }
        f[j][k] = l ? e(f[j], k + l, h) : h;
      } else {
        if (typeof f[j] !== 'object') {
          f[j] = [];
        }
        f[j].push(h);
      }
      return f[j];
    } else {
      if (f.hasOwnProperty(g)) {
        if (typeof f[g] === 'object') {
          f[g].push(h);
        } else {
          f[g] = [].concat.apply([f[g]], [h]);
        }
      } else {
        f[g] = h;
      }
      return f[g];
    }
  };
  b.split('&').forEach(function(m) {
    e(a, c(m.split('=')[0]), c(m.split('=')[1]));
  });
  return a;
};
share
1  
Looks broadly good, but why pre-minify it? It's tricky to follow in places as-is; in particular you're doing a few nasty things around the right-square-bracket line. Also an input something like c[xx=a&c[]=b will crash it. – Rup Jul 1 '14 at 12:22

Why not just use 2 splits ?

function get(n) {
      var half = location.search.split(n + '=')[1];
      return half !== undefined ? decodeURIComponent(half.split('&')[0]) : null;
  }

I was reading all previous and more complete answer. But I think that is the simplest and faster method. You can check in this jsPerf benchmark

To solve the problem in Rup's comment, add a conditional split by changing the first line to the two below. But absolute accuracy means it's now slower than regexp (see jsPerf).

function get(n) {
    var half = location.search.split('&' + n + '=')[1];
    if (!half) half = location.search.split('?' + n + '=')[1];
    return half !== undefined ? decodeURIComponent(half.split('&')[0]) : null;
}

So if you know you won't run into Rup's counter-case, this wins. Otherwise, regexp.

share
5  
Very neat! It won't work though if you have an earlier value with a key name that ends with the one you want, e.g. get('value') on http://the-url?oldvalue=1&value=2. – Rup Sep 4 '12 at 11:46
1  
However, if you know the parameter name are expecting, This will be the faster approach. – Martin Borthiry May 16 '13 at 17:57

Most pretty but basic:

data = {};
$.each(
    location.search.substr(1).split('&').filter(Boolean).map(function(kvpairs){
        return kvpairs.split('=')
    }),
    function(i,values) {
        data[values.shift()] = values.join('=')
    }
);

It doesn't handle values lists such as ?a[]=1&a[]2

share

Here is String prototype implementation:

String.prototype.getParam = function( str ){
    str = str.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
    var regex = new RegExp( "[\\?&]*"+str+"=([^&#]*)" );    
    var results = regex.exec( this );
    if( results == null ){
        return "";
    } else {
        return results[1];
    }
}

Example call:

var status = str.getParam("status")

str can be a query string or url

share

For those who wants a short method (with limitations):

location.search.split('myParameter=')[1]
share
3  
That's not enough for the general case: it assumes 1) that you're only interested in a single parameter 2) that it's guaranteed to be the last parameter in the line (i.e. you can guarantee that all browsers will put it last, or it's the only param on the page, and that you're not going to e.g. put the URL in an RSS feed aggregator where it might get utm parameters added) and 3) that there are no characters in the value that can be escaped for transmission, e.g. spaces or many symbols. – Rup Apr 14 '14 at 10:21
1  
There's no 1 size fits all methods. If you have a perfect solution in a one-short-liner, I'll be all eyes and ears to check that out. Above is a quick solution, not for general case, but for coders who want a light weight and quick solution to static implementations. In any case, thanks for your comment. – George Apr 14 '14 at 14:40
1  
(location.search.split('myParameter=')[1]).split('&')[0] ; this gives you the same result in case of multiple parameters. Still useful only for static implementations. – Anurag Aug 1 '14 at 7:05

quick, easy, and fast:

The Function:

    function getUrlVar() {
        var result = {};
        var location = window.location.href.split('#');
        var parts = location[0].replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
            result [key] = value;
        });
    return result ;
    }

Usage:

var varRequest = getUrlVar()["theUrlVarName"];
share

The shortest possible expression in terms of size to obtain a query object seems to be:

var params = {};
location.search.substr(1).replace(/([^&=]*)=([^&]*)&?/g,
  function () { params[decodeURIComponent(arguments[1])] = decodeURIComponent(arguments[2]); });

You can make use of the A element to parse a URI from a string into its location-like components (to get rid of #..., for example):

var a = document.createElement('a');
a.href = url;
// Parse a.search.substr(1)... as above
share

Simple Solution with Plain JS and Regex

alert(getQueryString("p2"));

function getQueryString (Param) {
      return decodeURI("http://www.example.com/?p1=p11&p2=p2222".replace(new RegExp("^(?:.*[&?]" + encodeURI(Param).replace(/[.+*]/g, "$&") + "(?:=([^&]*))?)?.*$", "i"), "$1"));
    }

JsFiddle

share

Get all querystring parameters including checkbox values (arrays).

Considering the a correct & normal use of GET parameters the things i see it's missing, on most functions, is the support for arrays and removing the hash data

So i wrote this function

function qs(a){
 if(!a)return {};
 a=a.split('#')[0].split('&');
 var b=a.length,c={},d,k,v;
 while(b--){
  d=a[b].split('=');
  k=d[0].replace('[]',''),v=decodeURIComponent(d[1]||'');
  c[k]?typeof c[k]==='string'?(c[k]=[v,c[k]]):(c[k].unshift(v)):c[k]=v;
 }
 return c
}

Using shorthand operators & while-- loop the performance should be very good to.

Support:

  1. empty values (key= / key)
  2. key value (key=value)
  3. arrays (key[]=value)
  4. hash (the hash tag is split out)

Notes:

It does not support object arrays (key[key]=value)

If the space is + it remains a +.

add .replace(/\+/g, " ") if you need.

Usage:

qs('array[]=1&array[]=2&key=value&empty=&empty2#hash')

Return:

{
    "empty": "",
    "key": "value",
    "array": [
        "1",
        "2"
    ]
}

Demo:

http://jsfiddle.net/ZQMrt/1/

Info

If you don't understand something or you can't read the function just ask i'm happy to explain what i did here.

If you think the function is unreadable and unmanainable i'm happy to rewrite the function for you , but consider that shorthand & bitwise operators are always faster than a standard syntax (mybe read about shorthands and bitwise operators in the ECMA-262 book or us your favorite searchengine).Rewriting the code in a standard readable syntax means performance loss.

share

protected by Community Oct 23 '11 at 15:27

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.