191

Anyone know of a good way to write a jQuery extension to handle query string parameters? I basically want to extend the jQuery magic ($) function so I can do something like this:

$('?search').val(); 

Which would give me the value "test" in the following URL: http://www.example.com/index.php?search=test.

I've seen a lot of functions that can do this in jQuery and Javascript, but I actually want to extend jQuery to work exactly as it is shown above. I'm not looking for a jQuery plugin, I'm looking for an extension to the jQuery method.

TroySteven
  • 4,885
  • 4
  • 32
  • 50
  • 4
    Asked and answered: http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript – Nico Westerdale Oct 11 '11 at 20:08
  • 1
    @NicoWesterdale - I went through that link, but didn't see any answers that solve this particular question. He said he wants exactly as above. – mrtsherman Oct 11 '11 at 20:12
  • 2
    I don't think you can do this, a string passed in gets parsed by sizzler, then resolved to an array of DOM objects. You can extend the matcher to provide custom filters, but you can't have a jquery object based on a string. – Andrew Oct 11 '11 at 20:24
  • 6
    Isn't `$` overloaded enough? – Quentin Oct 11 '11 at 20:30
  • 1
    @mrtsherman Look at the getParameterByName() function in the link I provided. No you can't do it from directly within a $ prompt, but that's not what jQuery selectors are for. He's just selecting part of a URL string, not trying to access part of the DOM which is what $() does. It's a totally different thing. If you really wanted to use jQuery you could write a plugin that used this syntax: $.getParameterByName(param), there's an example further down on that page I linked to that does exactly that. Kinda pointless though. – Nico Westerdale Oct 13 '11 at 13:54

10 Answers10

149

After years of ugly string parsing, there's a better way: URLSearchParams Let's have a look at how we can use this new API to get values from the location!

//Assuming URL has "?post=1234&action=edit"

var urlParams = new URLSearchParams(window.location.search);
console.log(urlParams.has('post')); // true
console.log(urlParams.get('action')); // "edit"
console.log(urlParams.getAll('action')); // ["edit"]
console.log(urlParams.toString()); // "?post=1234&action=edit"
console.log(urlParams.append('active', '1')); // "?

post=1234&action=edit&active=1"

UPDATE : IE is not supported

use this function from an answer below instead of URLSearchParams

$.urlParam = function (name) {
    var results = new RegExp('[\?&]' + name + '=([^&#]*)')
                      .exec(window.location.search);

    return (results !== null) ? results[1] || 0 : false;
}

console.log($.urlParam('action')); //edit
Vitor Ceolin
  • 196
  • 17
Saurin
  • 1,650
  • 1
  • 10
  • 8
  • 1
    is URLSearchParams supported by all browsers? – divine Jan 11 '18 at 11:44
  • Oops! ohh man, IE is not supported !! I have just tested on it. While Chrome, FF, Safari has no issue. – Saurin Jan 11 '18 at 13:49
  • 1
    @divine - There is a polyfill for URLSearchParams here: https://github.com/WebReflection/url-search-params – Yogi May 08 '19 at 12:16
  • If you add a polyfill for unsupported browsers this URLSearchParams solution works well. https://github.com/ungap/url-search-params – Louisvdw May 12 '20 at 16:57
  • wont work with say `https://mytest.com/bippo/#/?utm_source=teeest` or `https://mytest.com/bippo/#/url/?utm_source=teeest` – Toskan Aug 19 '20 at 01:58
  • The solution is not complete, il should call `decodeURIComponent`, and replace `+` with space... see previous solution – farialima Feb 17 '22 at 11:07
  • Another polyfill is https://github.com/jerrybendy/url-search-params-polyfill – Maytha8 Aug 04 '22 at 03:35
114

Why extend jQuery? What would be the benefit of extending jQuery vs just having a global function?

function qs(key) {
    key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, "\\$&"); // escape RegEx meta chars
    var match = location.search.match(new RegExp("[?&]"+key+"=([^&]+)(&|$)"));
    return match && decodeURIComponent(match[1].replace(/\+/g, " "));
}

http://jsfiddle.net/gilly3/sgxcL/

An alternative approach would be to parse the entire query string and store the values in an object for later use. This approach doesn't require a regular expression and extends the window.location object (but, could just as easily use a global variable):

location.queryString = {};
location.search.substr(1).split("&").forEach(function (pair) {
    if (pair === "") return;
    var parts = pair.split("=");
    location.queryString[parts[0]] = parts[1] &&
        decodeURIComponent(parts[1].replace(/\+/g, " "));
});

http://jsfiddle.net/gilly3/YnCeu/

This version also makes use of Array.forEach(), which is unavailable natively in IE7 and IE8. It can be added by using the implementation at MDN, or you can use jQuery's $.each() instead.

gilly3
  • 87,962
  • 25
  • 144
  • 176
  • 2
    It's not common but it is valid to use semi-colons instead of ampersands in the query parameters. – Muhd Nov 18 '11 at 00:38
  • @Muhd - It's "valid" to use any delimiter you like in a querystring as long as your code understands it. But, when a form is submitted, the form fields are submitted as `name=value` pairs, separated by `&`. If your code is using a custom querystring format, obviously, you'll need to write a custom querystring parser wherever the querystring is consumed, whether on the server or the client. – gilly3 Nov 18 '11 at 18:04
  • The W3C recommendation is to use semi-colon delimiters, see http://www.w3.org/TR/1999/REC-html401-19991224/appendix/notes.html#h-B.2.2 – nick May 24 '12 at 13:41
  • 2
    @nick - Interesting. But their suggestion for HTTP servers to treat semi-colons as ampersands only serves to make HTML prettier when using a link to mimic a form submission. It is just a suggestion and is non-standard. A standard form `GET` submission is encoded as [`application/x-www-form-urlencoded`](http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1), with values separated by `&`. My code handles that standard. Custom url structures such as the one you linked will need a custom parser server-side and client-side. Regardless, adding such capability to my code above would be trivial. – gilly3 May 24 '12 at 19:50
  • 1
    @gilly indeed - if you want portable code you need to support both – nick May 25 '12 at 11:42
  • 2
    Add "i" to the RegExp() so the key can be case insensitive: new RegExp("[?&]"+key+"=([^&]+)(&|$)", "i")); – Yovav Dec 05 '17 at 01:25
  • This properly handled where a query param contained a plus (+) sign, while other examples did not. – Volomike May 04 '19 at 22:16
  • dont understand the jsfiddle. Will this work for example with: `https://mytest.com/bippo/#/url/?utm_source=teeest` – Toskan Aug 19 '20 at 02:04
  • @Toskan - You can adapt it to work. I assume you want to treat the `?utm_source=teeest` portion as the querystring. Since that portion in your URL comes after the `#`, it's not part of the traditional querystring, and thus not available in `location.search`, which both of my examples rely on. You can modify my `qs` function to use `location.hash` instead of `location.search` and it will work. – gilly3 Aug 24 '20 at 19:17
96

JQuery jQuery-URL-Parser plugin do the same job, for example to retrieve the value of search query string param, you can use

$.url().param('search');

This library is not actively maintained. As suggested by the author of the same plugin, you can use URI.js.

Or you can use js-url instead. Its quite similar to the one below.

So you can access the query param like $.url('?search')

RameshVel
  • 64,778
  • 30
  • 169
  • 213
  • 2
    Nice. And the code is in the public domain so you don't even have to include the comments. – Muhd Nov 18 '11 at 00:52
  • 4
    Good solution but won't work if you happen to be testing via file:// – kampsj Jan 24 '14 at 20:02
  • 1
    Whats that have to do anything with, @kampsj – RameshVel Jan 24 '14 at 20:45
  • 3
    Hi @kampsj, testing with `file://` protocol will cause a lot more stuff not to work. You can create a very quick and easy static HTML server with node.js. http://stackoverflow.com/questions/16333790/node-js-quick-file-server-static-files-over-http – Jess May 30 '14 at 14:00
  • Why we need plugin for very small task? – Kalidasan Dec 10 '15 at 14:25
  • 1
    Its based on the needs, if you are pereforming more than just retrieving a field from URL.. So if you dont want to use a plugin, then checkout the answers below, there are lot of alternatives – RameshVel Dec 10 '15 at 15:56
  • 2
    This plugin is no longer maintained and the author itself is suggesting to use other plugins instead. – JanErikGunnar Oct 16 '17 at 10:33
  • thanks @JanErikGunnar, Please check the updated answer – RameshVel Oct 16 '17 at 13:48
  • 1
    @RameshVel Did you intend for both URI.js and js-url links to point to the same location? Maybe you meant js-url to point [here](https://github.com/websanova/js-url)? – M.Babcock Jan 30 '18 at 19:40
  • @M.Babcock yep the link was wrong. fixed now. thank you – RameshVel Jan 31 '18 at 06:18
95

Found this gem from our friends over at SitePoint. https://www.sitepoint.com/url-parameters-jquery/.

Using PURE jQuery. I just used this and it worked. Tweaked it a bit for example sake.

//URL is http://www.example.com/mypage?ref=registration&email=bobo@example.com

$.urlParam = function (name) {
    var results = new RegExp('[\?&]' + name + '=([^&#]*)')
                      .exec(window.location.search);

    return (results !== null) ? results[1] || 0 : false;
}

console.log($.urlParam('ref')); //registration
console.log($.urlParam('email')); //bobo@example.com

Use as you will.

Nick.Mc
  • 18,304
  • 6
  • 61
  • 91
ClosDesign
  • 3,894
  • 9
  • 39
  • 62
  • Great. Thanks! I don't think you need the last closing brace tag though. – bhtabor Dec 20 '16 at 10:18
  • Ahh yes, you are correct. Edited the post. That was left over from some if statement in my code. Thanks. – ClosDesign Dec 21 '16 at 15:14
  • 1
    You should use window.location.search instead of .href -- otherwise, good. – BrainSlugs83 Jan 28 '17 at 01:03
  • 4
    Instead of `results[1] || 0`, you must do if (results) {return results[1]} return 0; bcoz query parameters may not be present at all. And modifying will handle all generic cases. – master_dodo May 24 '17 at 12:48
  • The return statement should be `return (results && results[1]) || 0;` – Shane Rowatt Apr 07 '18 at 02:11
  • If the param is not set, it'll return `null`, and cause an error. I modified it to: `return (results !== null) ? results[1] || 0 : false;` to solve the issue. This way it'll return `false` if the param is not set. Thanks for the solution. – dnns May 01 '18 at 21:35
  • 2
    What do you do if you have something like `https://example.com/?c=Order+ID` ? That plus sign still remains on this function. – Volomike May 04 '19 at 22:12
  • 1
    "Using PURE jQuery." This solution doesn't actually use any JQuery. It only extends JQuery with what could just as easily be a stand alone function. – Code-Apprentice May 14 '19 at 00:34
  • To get rid of the plus sign and decode use `decodeURIComponent($.urlParam('email').replace(/\+/g," "));` – Carter Medlin Jul 19 '19 at 18:15
  • wont work with `https://mytest.com/bippo/#/url/?utm_source=teeest` – Toskan Aug 19 '20 at 02:05
  • $.urlParam = function(name){ var results = new RegExp('[\?&]' + name + '=([^]*)').exec(window.location.href); if (results==null){ return null; } else{ return results[1] || 0; } } – Alejandro Haro Aug 17 '22 at 16:35
47

This isn't my code sample, but I've used it in the past.

//First Add this to extend jQuery

    $.extend({
      getUrlVars: function(){
        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;
      },
      getUrlVar: function(name){
        return $.getUrlVars()[name];
      }
    });

    //Second call with this:
    // Get object of URL parameters
    var allVars = $.getUrlVars();

    // Getting URL var by its name
    var byName = $.getUrlVar('name');
Kingpin2k
  • 47,277
  • 10
  • 78
  • 96
Rob Nield
  • 504
  • 3
  • 2
  • 2
    You shouldn't split on '=', it's technically okay to have a second equals sign in the value of any key/value pair. -- Only the first equals sign you encounter (per key/value pair) should be treated as a delimiter. (Also, the equals sign isn't strictly required; it's possible to have a key with no value.) – BrainSlugs83 Jan 28 '17 at 01:00
  • Clean solution. Worked perfectly in my case. – JF Gagnon Dec 20 '19 at 12:38
  • $.extend({ getUrlVars: function(){ 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('='); var k = hash.shift(); vars.push(k); vars[k] = hash.join(""); } return vars; }, getUrlVar: function(name){ return $.getUrlVars()[name]; } }); – Mupinc Apr 27 '20 at 13:09
16

I wrote a little function where you only have to parse the name of the query parameter. So if you have: ?Project=12&Mode=200&date=2013-05-27 and you want the 'Mode' parameter you only have to parse the 'Mode' name into the function:

function getParameterByName( name ){
    var regexS = "[\\?&]"+name+"=([^&#]*)", 
  regex = new RegExp( regexS ),
  results = regex.exec( window.location.search );
  if( results == null ){
    return "";
  } else{
    return decodeURIComponent(results[1].replace(/\+/g, " "));
  }
}

// example caller:
var result =  getParameterByName('Mode');
Plippie
  • 2,836
  • 33
  • 28
  • If your name has no junk, you can drop the first regex and it make more sense to start from location.search – mplungjan Sep 29 '13 at 05:07
8

Building on @Rob Neild's answer above, here is a pure JS adaptation that returns a simple object of decoded query string params (no %20's, etc).

function parseQueryString () {
  var parsedParameters = {},
    uriParameters = location.search.substr(1).split('&');

  for (var i = 0; i < uriParameters.length; i++) {
    var parameter = uriParameters[i].split('=');
    parsedParameters[parameter[0]] = decodeURIComponent(parameter[1]);
  }

  return parsedParameters;
}
  • I haven't seen any erroring using this code. What browser are you using? I've tested it against current Firefox, Chrome, and Safari. –  Mar 17 '17 at 23:22
  • Yeah sorry I read it wrong. I thought I saw it call a method on something that was returning undefined. So really it's just running once when it doesn't have to. When search is `""`. And you get {"": "undefined"} – Jerinaw Mar 19 '17 at 00:27
  • Yeah. That could probably use some refining. –  Mar 19 '17 at 04:48
3
function parseQueryString(queryString) {
    if (!queryString) {
        return false;
    }

    let queries = queryString.split("&"), params = {}, temp;

    for (let i = 0, l = queries.length; i < l; i++) {
        temp = queries[i].split('=');
        if (temp[1] !== '') {
            params[temp[0]] = temp[1];
        }
    }
    return params;
}

I use this.

donvercety
  • 221
  • 2
  • 7
2

Written in Vanilla Javascript

     //Get URL
     var loc = window.location.href;
     console.log(loc);
     var index = loc.indexOf("?");
     console.log(loc.substr(index+1));
     var splitted = loc.substr(index+1).split('&');
     console.log(splitted);
     var paramObj = [];
     for(var i=0;i<splitted.length;i++){
         var params = splitted[i].split('=');
         var key = params[0];
         var value = params[1];
         var obj = {
             [key] : value
         };
         paramObj.push(obj);
         }
    console.log(paramObj);
    //Loop through paramObj to get all the params in query string.
manish Prasad
  • 636
  • 6
  • 16
1

function getQueryStringValue(uri, key) {        
        var regEx = new RegExp("[\\?&]" + key + "=([^&#]*)");        
        var matches = uri.match(regEx);
        return matches == null ? null : matches[1];
}

function testQueryString(){
   var uri = document.getElementById("uri").value;
   var searchKey = document.getElementById("searchKey").value;
   var result = getQueryStringValue(uri, searchKey);
   document.getElementById("result").value = result;
}
<input type="text" id="uri" placeholder="Uri"/>
<input type="text" id="searchKey" placeholder="Search Key"/>
<Button onclick="testQueryString()">Run</Button><br/>

<input type="text" id="result" disabled placeholder="Result"/>
Roshin Raj V
  • 201
  • 2
  • 2