Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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

74 Answers 74

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
3  
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

These are all great answers, but I needed something a bit more robust, and thought you all might like to have what I created. It is a simple library method that does dissection and manipulation of url parameters. The static method has the following sub methods that can be called on the subject url:

  • getHost
  • getPath
  • getHash
  • setHash
  • getParams
  • getQuery
  • setParam
  • getParam
  • hasParam
  • removeParam

Example:

URLParser(url).getParam('myparam1')

var url = "http://www.test.com/folder/mypage.html?myparam1=1&myparam2=2#something";

function URLParser(u){
    var path="",query="",hash="",params;
    if(u.indexOf("#") > 0){
        hash = u.substr(u.indexOf("#") + 1);
        u = u.substr(0 , u.indexOf("#"));
    }
    if(u.indexOf("?") > 0){
        path = u.substr(0 , u.indexOf("?"));        
        query = u.substr(u.indexOf("?") + 1);
        params= query.split('&');
    }else
        path = u;
    return {
        getHost: function(){
            var hostexp = /\/\/([\w.-]*)/;
            var match = hostexp.exec(path);
            if (match != null && match.length > 1)
                return match[1];
            return "";
        },
        getPath: function(){
            var pathexp = /\/\/[\w.-]*(?:\/([^?]*))/;
            var match = pathexp.exec(path);
            if (match != null && match.length > 1)
                return match[1];
            return "";
        },
        getHash: function(){
            return hash;
        },
        getParams: function(){
            return params
        },
        getQuery: function(){
            return query;
        },
        setHash: function(value){
            if(query.length > 0)
                query = "?" + query;
            if(value.length > 0)
                query = query + "#" + value;
            return path + query;
        },
        setParam: function(name, value){
            if(!params){
                params= new Array();
            }
            params.push(name + '=' + value);
            for (var i = 0; i < params.length; i++) {
                if(query.length > 0)
                    query += "&";
                query += params[i];
            }
            if(query.length > 0)
                query = "?" + query;
            if(hash.length > 0)
                query = query + "#" + hash;
            return path + query;
        },
        getParam: function(name){
            if(params){
                for (var i = 0; i < params.length; i++) {
                    var pair = params[i].split('=');
                    if (decodeURIComponent(pair[0]) == name)
                        return decodeURIComponent(pair[1]);
                }
            }
            console.log('Query variable %s not found', name);
        },
        hasParam: function(name){
            if(params){
                for (var i = 0; i < params.length; i++) {
                    var pair = params[i].split('=');
                    if (decodeURIComponent(pair[0]) == name)
                        return true;
                }
            }
            console.log('Query variable %s not found', name);
        },
        removeParam: function(name){
            query = "";
            if(params){
                var newparams = new Array();
                for (var i = 0;i < params.length;i++) {
                    var pair = params[i].split('=');
                    if (decodeURIComponent(pair[0]) != name)
                          newparams .push(params[i]);
                }
                params = newparams ;
                for (var i = 0; i < params.length; i++) {
                    if(query.length > 0)
                        query += "&";
                    query += params[i];
                }
            }
            if(query.length > 0)
                query = "?" + query;
            if(hash.length > 0)
                query = query + "#" + hash;
            return path + query;
        },
    }
}


document.write("Host: " + URLParser(url).getHost() + '<br>');
document.write("Path: " + URLParser(url).getPath() + '<br>');
document.write("Query: " + URLParser(url).getQuery() + '<br>');
document.write("Hash: " + URLParser(url).getHash() + '<br>');
document.write("Params Array: " + URLParser(url).getParams() + '<br>');
document.write("Param: " + URLParser(url).getParam('myparam1') + '<br>');
document.write("Has Param: " + URLParser(url).hasParam('myparam1') + '<br>');

document.write(url + '<br>');

// Remove first param
url = URLParser(url).removeParam('myparam1');
document.write(url + ' - Remove first param<br>');

// Add third param
url = URLParser(url).setParam('myparam3',3);
document.write(url + ' - Add third param<br>');

// Remove second param
url = URLParser(url).removeParam('myparam2');
document.write(url + ' - Add third param<br>');

// Add hash 
url = URLParser(url).setHash('newhash');
document.write(url + ' - Set Hash<br>');

// Remove last param
url = URLParser(url).removeParam('myparam3');
document.write(url + ' - Remove last param<br>');

// Remove a param that doesnt exist
url = URLParser(url).removeParam('myparam3');
document.write(url + ' - Remove a param that doesnt exist<br>');

​
share

This function converts the querystring to a JSON-like object, it also handles value-less and multi-value parameters:

"use strict";
function getQuerystringData(name) {
    var data = { };
    var parameters = window.location.search.substring(1).split("&");
    for (var i = 0, j = parameters.length; i < j; i++) {
        var parameter = parameters[i].split("=");
        var parameterName = decodeURIComponent(parameter[0]);
        var parameterValue = typeof parameter[1] === "undefined" ? parameter[1] : decodeURIComponent(parameter[1]);
        var dataType = typeof data[parameterName];
        if (dataType === "undefined") {
            data[parameterName] = parameterValue;
        } else if (dataType === "array") {
            data[parameterName].push(parameterValue);
        } else {
            data[parameterName] = [data[parameterName]];
            data[parameterName].push(parameterValue);
        }
    }
    return typeof name === "string" ? data[name] : data;
}

We perform a check for undefined on parameter[1] because decodeURIComponent returns the string "undefined" if the variable is undefined, and that's wrong.

Usage:

"use strict";
var data = getQuerystringData();
var parameterValue = getQuerystringData("parameterName");
share

There is a nice little url utility for this with some cool sugaring:

http://www.example.com/path/index.html?silly=willy#chucky=cheese

url();            // http://www.example.com/path/index.html?silly=willy#chucky=cheese
url('domain');    // example.com
url('1');         // path
url('-1');        // index.html
url('?');         // silly=willy
url('?silly');    // willy
url('?poo');      // (an empty string)
url('#');         // chucky=cheese
url('#chucky');   // cheese
url('#poo');      // (an empty string)

Check out more examples and download here: https://github.com/websanova/js-url#url

share

One line code to get Query

var value = location.search.match(new RegExp(key + "=(.*?)($|\&)", "i"))[1];
share
5  
Triggers error if the key doesn't exist, try this maybe? (location.search.match(new RegExp('kiosk_modeasdf' + "=(.*?)($|\&)", "i")) || [])[1] –  Brad Koch Jan 28 '13 at 20:51

This the most simple and small function JavaScript to get int ans String parameter value from URL

/* THIS FUNCTION IS TO FETCH INT PARAMETER VALUES */

function getParameterint(param) {
            var val = document.URL;
            var url = val.substr(val.indexOf(param))  
            var n=parseInt(url.replace(param+"=",""));
            alert(n); 
}
getParameteraint("page");
getParameteraint("pagee");

/*THIS FUNCTION IS TO FETCH STRING PARAMETER*/
function getParameterstr(param) {
            var val = document.URL;
            var url = val.substr(val.indexOf(param))  
            var n=url.replace(param+"=","");
            alert(n); 
}
getParameterstr("str");

Source And DEMO : http://bloggerplugnplay.blogspot.in/2012/08/how-to-get-url-parameter-in-javascript.html

share
1  
I think that can be easily defeated e.g. ?xyz=page&str=Expected&page=123 won't return 123 because it picks up the page string from xyz=page, and str will return Expected&page=123 rather than just Expected if it's not the last value on the line, etc. You're also not decodeUriComponent-ing the values extracted. Plus I couldn't try your demo - I got redirected to a betting website?? –  Rup Jan 25 '13 at 12:23
1  
OK, finally managed to get your demo through adfly. Yes, that works OK but only because you have just the one string parameter and it's last - try using more than one and switching the orders around. Try putting the pagee parameter before the page parameter and it'll fail. For example here's your demo with the order of the three reversed. The other problem is if someone posts a string with a non-ASCII character in it, e.g. a space - it'll get URI encoded and you're not decoding that afterwards. –  Rup Jan 29 '13 at 11:49

I developed a small library using techniques listed here to create an easy to use, drop-in solution to anyones troubles; It can be found here:

https://github.com/Nijikokun/query-js

Usage

Fetching specific parameter/key:

query.get('param');

Using the builder to fetch the entire object:

var storage = query.build();
console.log(storage.param);

and tons more... check the github link for more examples.

Features

  1. Caching on both decoding and parameters
  2. Supports hash query strings #hello?page=3
  3. Supports passing custom queries
  4. Supports Array / Object Parameters user[]="jim"&user[]="bob"
  5. Supports empty management &&
  6. Supports declaration parameters without values name&hello="world"
  7. Supports repeated parameters param=1&param=2
  8. Clean, compact, and readable source 4kb
  9. AMD, Require, Node support
share
function GetQueryStringParams(sParam)
{
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');

    for (var i = 0; i < sURLVariables.length; i++)
    {
        var sParameterName = sURLVariables[i].split('=');
        if (sParameterName[0] == sParam)
        {
            return sParameterName[1];
        }
    }
}​

And this is how you can use this function assuming the URL is

http://dummy.com/?stringtext=jquery&stringword=jquerybyexample

var tech = GetQueryStringParams('stringtext');
var blog = GetQueryStringParams('stringword');
share

From the MDN:

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

alert(loadPageVar("name"));
share

I'm gonna throw my hat in the ring - I needed an object from the query string, and I hate lots of code. may not be the most robust in the universe but it's just a few lines of code.

var q = {};
location.href.split('?')[1].split('&').forEach(function(i){
    q[i.split('=')[0]]=i.split('=')[1];
});

a URL like this.htm?hello=world&foo=bar will create:

{hello:'world', foo:'bar'}
share
3  
Neat. According to Mozilla, though, forEach doesn't work on IE7 or 8 and I suspect that'll fall over if there's no query string at all. One minimal improvement that would cover more cases would be to decodeURIComponent the value as you store it - and arguably the key as well, but you're less likely to use odd strings in that. –  Rup Feb 15 '13 at 10:39
1  
Nice and simple. Doesn't handle array parameters nor ?a&b&c but this is really very readable (and incidentally similar to my first idea). Also the split is redundant but I've got bigger performance fish to fry than splitting a 10 character string twice. –  cod3monk3y Feb 25 '14 at 22:44

I believe this to be an accurate and concise way to achieve this (modified from http://css-tricks.com/snippets/javascript/get-url-variables/):

function getQueryVariable(variable) {

    var query = window.location.search.substring(1),            // Remove the ? from the query string.
        vars = query.split("&");                                // Split all values by ampersand.

    for (var i = 0; i < vars.length; i++) {                     // Loop through them...
        var pair = vars[i].split("=");                          // Split the name from the value.
        if (pair[0] == variable) {                              // Once the requested value is found...
            return ( pair[1] == undefined ) ? null : pair[1];   // Return null if there is no value (no equals sign), otherwise return the value.
        }
    }

    return undefined;                                           // Wasn't found.

}
share

A very lightweight jquery method:

var qs = window.location.search.replace('?','').split('&'),
    request = {};
$.each(qs, function(i,v) {
    var pair = v.split('=');
    return request[pair[0]] = pair[1];
});
console.log(request);

And to alert ,for example ?q

alert(request.q)
share
1  
Neat. There's a few answers in the same vein already - iterating over a split - albeit none using jQuery's each, and I don't think any of them are perfect yet either. I don't understand the return in your closure though, and I think you need to decodeUriComponent the two pair[] values as you read them. –  Rup Apr 2 '13 at 8:48

If you want array-style parameters URL.js supports arbitrarily nested array-style parameters as well as string indexes (maps). It also handles url-decoding.

url.get("val[0]=zero&val[1]=one&val[2]&val[3]=&val[4]=four&val[5][0]=n1&val[5][1]=n2&val[5][2]=n3&key=val", {array:true});
// Result
{
    val: [
        'zero',
        'one',
        true,
        '',
        'four',
        [ 'n1', 'n2', 'n3' ]
    ]
    key: 'val'
}
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

I did small URL library for my needs here: https://github.com/Mikhus/jsurl

It's more common way of manipulating the URLs in JavaScript, meanwhile it's really lightweight (minified and gzipped < 1KB) and has very simple and clean API. And it does not need any other library to work.

Regarding the initial question, it's very simply to do:

var u = new Url; // current document url
// or
var u = new Url('http://user:[email protected]:8080/some/path?foo=bar&bar=baz#anchor');

// looking for query string params
alert( u.query.bar);
alert( u.query.foo);

// modifying query string params
u.query.foo = 'bla';
u.query.woo = ['hi', 'hey']

alert( u.query.foo);
alert( u.query.woo);
alert( u);
share

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: http://nodejs.org/api/url.html

share
3  
As the question mentions jQuery, I would assume this is in the browser. –  Luca Spiller May 16 '13 at 9:31

If you do not wish to use a Javascript library you can use the Javascript string functions to parse window.location. Keep this code in an external .js file and you can use it over and over again in different projects.

// Example - window.location = "index.htm?name=bob";

var value = getParameterValue("name");

alert("name = " + value);

function getParameterValue(param)
{
     var url = window.location;
     var parts = url.split('?');
     var params = parts[1].split('&');
     var val = "";

     for ( var i=0; i<params.length; i++)
     {
          var paramNameVal = params[i].split('=');

          if ( paramNameVal[0] == param )
          {
              val = paramNameVal[1];
          }
     }

     return val;
}
share

see this post or use this

<script type="text/javascript" language="javascript">
$(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;
    }
});
</script>
share

I recommend Dar Lessons as a good plugin. I have worked with it fo a long time. You can also use the following code. Jus put var queryObj = {}; before document.ready and put the bellow code in the beginning of document.ready. After this code you can use queryObj["queryObjectName"] for any query object you have

var querystring = location.search.replace('?', '').split('&');
for (var i = 0; i < querystring.length; i++) {
    var name = querystring[i].split('=')[0];
    var value = querystring[i].split('=')[1];
    queryObj[name] = value;
}
share
<script type="text/javascript" language="javascript">
    $(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 : http://jquerybyexample.blogspot.com/2012/05/how-to-get-querystring-value-using.html

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

There's a robust implementation in Node.js's source
https://github.com/joyent/node/blob/master/lib/querystring.js

Also TJ's qs does nested params parsing
https://github.com/visionmedia/node-querystring

share
var getUrlParameters = function (name, url) {
    if (!name) {
        return undefined;
    }

    name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
    url = url || location.search;

    var regex = new RegExp('[\\?&#]' + name + '=?([^&#]*)', 'gi'), result, resultList = [];

    while (result = regex.exec(url)) {
        resultList.push(decodeURIComponent(result[1].replace(/\+/g, ' ')));
    }

    return resultList.length ? resultList.length === 1 ? resultList[0] : resultList : undefined;
};
share

I used this code (JavaScript) to get the what is passed through the URL:

function getUrlVars() {
            var vars = {};
            var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
                vars[key] = value;
            });
            return vars;
        }

Then to assign the value to a variable, you only have to specify which parameter you want to get, ie if the URL is example.com/?I=1&p=2&f=3

You can do this to get the values:

var getI = getUrlVars()["I"];
var getP = getUrlVars()["p"];
var getF = getUrlVars()["f"];

then the values would be:

getI = 1, getP = 2 and getF = 3

Thanks, Josh

share

There are many solutions to retrieve URI query values, I prefer this one because it's short and works great:

function get(name){
   if(name=(new RegExp('[?&]'+encodeURIComponent(name)+'=([^&]*)')).exec(location.search))
      return decodeURIComponent(name[1]);
}
share

This is very simple method to get parameter value(query string)

Use gV(para_name) function to retrieve its value

var a=window.location.search;
a=a.replace(a.charAt(0),""); //Removes '?'
a=a.split("&");

function gV(x){
 for(i=0;i<a.length;i++){
  var b=a[i].substr(0,a[i].indexOf("="));
  if(x==b){
   return a[i].substr(a[i].indexOf("=")+1,a[i].length)}
share

We've just released arg.js, a project aimed at solving this problem once and for all. It's traditionally been so difficult but now you can do:

var name = Arg.get("name");

or getting the whole lot:

var params = Arg.all();

and if you care about the difference between ?query=true and #hash=true then you can use the Arg.query() and Arg.hash() methods.

share

Not to beat a dead horse, but if you have underscore or lodash, a quick and dirty way to get this done is:

_.object(window.location.search.slice(1).split('&').map(function (val) { return val.split('='); }));
share
1  
this is what I use to make a key value object of the query parameters: _.chain(document.location.search.slice(1).split('&')).invoke('split', '=').object().value() –  David Fregoli Jan 7 '14 at 14:46

tl;dr

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

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=2&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: ["2"]
c: ["3"]
d: [undefined]
e: [undefined, "http://w3schools.com/my test.asp?name=ståle&car=saab"]

... 

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=2&c=3&d&e&a=5"
> queryDict
a: "5"
b: "2"
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: ["2"]
c: ["3"]
d: [undefined]
e: [undefined]

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

encoded characters?

Enclose the item.split("=")[1] by decodeURIComponent(item.split("=")[1])
(as shown at the top)

"?a=1&b=2&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: ["2"]
c: ["3"]
d: [undefined]
e: [undefined, "http://w3schools.com/my test.asp?name=ståle&car=saab"]
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  
Glad I looked at this post for an updated solution. Thanks for submitting this. It'll work across all browsers too! –  twig Jan 20 '14 at 22:57
1  
Thanks. I wrapped decodeURIComponent() in a function that replaces plus signs with spaces, as shown by @AndyE. For one particular application, if there is no query (search) string, I want to fall back on getting parameters from the hash value instead, so I use a conditional (ternary) operator inside bracket notation, like this: location[location.search.length ? "search" : "hash"] –  Graham Hannington Aug 8 '14 at 4:52
1  
Fine stuff, pity that we have to scroll down so much to find something that's not Regex or overly complicated. ++1 –  brasofilo Sep 22 '14 at 22:21
1  
@ripounet is it possible to mark this as the correct answer? +1 for simplicity AND solving for all the valid options –  Ascherer Jan 19 at 21:47

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

This will parse variables AND arrays from a URL string. It uses neither regex or any external library.

function url2json(url) {
   var obj={};
   function arr_vals(arr){
      if (arr.indexOf(',') > 1){
         var vals = arr.slice(1, -1).split(',');
         var arr = [];
         for (var i = 0; i < vals.length; i++)
            arr[i]=vals[i];
         return arr;
      }
      else
         return arr.slice(1, -1);
   }
   function eval_var(avar){
      if (!avar[1])
          obj[avar[0]] = '';
      else
      if (avar[1].indexOf('[') == 0)
         obj[avar[0]] = arr_vals(avar[1]);
      else
         obj[avar[0]] = avar[1];
   }
   if (url.indexOf('?') > -1){
      var params = url.split('?')[1];
      if(params.indexOf('&') > 2){
         var vars = params.split('&');
         for (var i in vars)
            eval_var(vars[i].split('='));
      }
      else
         eval_var(params.split('='));
   }
   return obj;
}

Example:

var url = "http://www.x.com?luckyNums=[31,21,6]&name=John&favFoods=[pizza]&noVal"
console.log(url2json(url));

Output:

[object]
   noVal: ""
   favFoods: "pizza"
   name:     "John"
   luckyNums:
      0: "31"
      1: "21"
      2: "6"
share

protected by Community Oct 23 '11 at 15:27

Thank you for your interest in this question. Because it has attracted low-quality answers, 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.