108

Possible Duplicate:
Use the get paramater of the url in javascript
How can I get query string values in JavaScript?

In Javascript, how can I get the parameters of a URL string (not the current URL)?

like:

www.domain.com/?v=123&p=hello

Can I get "v" and "p" in a JSON object?

handle
  • 5,859
  • 3
  • 54
  • 82
user847495
  • 9,831
  • 17
  • 45
  • 48
  • 2
    You can check out this post on the matter http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript – Erik Nordenhök Dec 13 '11 at 08:19
  • Here's a nice little [snippet](http://www.onlineaspect.com/2009/06/10/reading-get-variables-with-javascript/). – Purag Dec 13 '11 at 08:24
  • check ans without regular expression http://stackoverflow.com/questions/19491336/get-url-parameter-jquery/21903119?noredirect=1#comment47504324_21903119 – Sameer Kazi Apr 17 '15 at 03:23
  • 5
    One of the duplicate questions has [a great answer using the native, modern built-in `URLSearchParams` object](https://stackoverflow.com/a/39620299/1327983). See also [MDN's doc page](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams). Polyfills available. – alttag Sep 05 '18 at 01:31
  • 3
    One liner : `new URL("http://www.example.com/?v=123&p=hello").searchParams.toString().split("&").reduce((previous, current)=> { const [key, value] = current.split("="); previous[key] = value; return previous },{})` – Flavien Volken Aug 29 '19 at 09:39
  • The `URLSearchParams` API is the way to go, but be wary of the lack of IE support: https://caniuse.com/#search=URL – Chris Hayes Jul 07 '20 at 16:06

2 Answers2

157

2.5 years after the question was asked you can safely use Array.forEach. As @ricosrealm suggests, decodeURIComponent was used in this function.

function getJsonFromUrl(url) {
  if(!url) url = location.search;
  var query = url.substr(1);
  var result = {};
  query.split("&").forEach(function(part) {
    var item = part.split("=");
    result[item[0]] = decodeURIComponent(item[1]);
  });
  return result;
}

actually it's not that simple, see the peer-review in the comments, especially:

  • hash based routing (@cmfolio)
  • array parameters (@user2368055)
  • proper use of decodeURIComponent and non-encoded = (@AndrewF)
  • non-encoded + (added by me)

For further details, see MDN article and RFC 3986.

Maybe this should go to codereview SE, but here is safer and regexp-free code:

function getSearchOrHashBased(url) {
  if(!url) url = location.href;
  var question = url.indexOf("?");
  var hash = url.indexOf("#");
  if(hash==-1 && question==-1) return {};
  if(hash==-1) hash = url.length;
  return question==-1 || hash==question+1
    ? url.substring(hash)
    : url.substring(question+1, hash);
}

// use query = getSearchOrHashBased(location.href)
// or query = location.search.substring(1)
function getJsonFromUrl(query) {
  var result = {};
  query.split("&").forEach(function(part) {
    if(!part) return;
    part = part.split("+").join(" "); // + to space, regexp-free version
    var eq = part.indexOf("=");
    var key = eq>-1 ? part.substr(0,eq) : part;
    var val = eq>-1 ? decodeURIComponent(part.substr(eq+1)) : "";
    var from = key.indexOf("[");
    if(from==-1) result[decodeURIComponent(key)] = val;
    else {
      var to = key.indexOf("]",from);
      var index = decodeURIComponent(key.substring(from+1,to));
      key = decodeURIComponent(key.substring(0,from));
      if(!result[key]) result[key] = [];
      if(!index) result[key].push(val);
      else result[key][index] = val;
    }
  });
  return result;
}

This function can parse even URLs like

var url = "?foo%20e[]=a%20a&foo+e[%5Bx%5D]=b&foo e[]=c";
// {"foo e": ["a a",  "c",  "[x]":"b"]}

var obj = getJsonFromUrl(url)["foo e"];
for(var key in obj) { // Array.forEach would skip string keys here
  console.log(key,":",obj[key]);
}
/*
  0 : a a
  1 : c
  [x] : b
*/

7 years after the question was asked the functionality was standardized as URLSearchParams and 4 more years after, the access can be further simplified by Proxy as explained in this answer, however that new one can not parse the sample url above.

Jan Turoň
  • 31,451
  • 23
  • 125
  • 169
  • 7
    Each item should be url decoded using decodeURIComponent() – ricosrealm Jan 17 '14 at 00:40
  • `location.search` doesn't work on hash based routing: `http://localhost:9000/#/documents?lang=es` will return an empty string for `location.search`. You would have to use `location.hash` or `location.href` instead. – cmfolio Sep 30 '14 at 16:58
  • this wont work for array parameters – user2368055 Nov 12 '14 at 10:26
  • Good thoughts, cmfolio & user2368055, I added your points to the answer. – Jan Turoň Nov 12 '14 at 20:40
  • check ans without regular expression http://stackoverflow.com/questions/19491336/get-url-parameter-jquery/21903119?noredirect=1#comment47504324_21903119 – Sameer Kazi Apr 17 '15 at 03:26
  • 2
    Both the parameter name and value must be decoded. This is a common mistake. So rather than `result[item[0]] = decodeURIComponent(item[1]);` it should be: `result[decodeURIComponent(item[0])] = decodeURIComponent(item[1]);` – AndrewF Oct 02 '15 at 17:49
  • 1
    Note also that using `split("=")` will fail for param values that contain an unencoded =, which is uncommon but certainly does happen. I would suggest using a regular expression so that you get better logic while keeping succinctness. – AndrewF Oct 02 '15 at 18:08
  • @AndrewF good point, I also decoded the index if the URI parameter is associative array. – Jan Turoň Oct 25 '15 at 13:48
  • Is there a reason to use `decodeURIComponent` several times instead of `decodeURI` once ? – Guillermo Moscoso Jan 20 '16 at 14:21
  • 1
    @GuillermoMoscoso Then you would get strings like `genre=R&B&name=John` which could not be parsed correctly. You need to decode after you split the string and know what is key and what is value, square brackets as "key in keys" need special care here, see the code. – Jan Turoň Jan 20 '16 at 15:48
  • @JanTuroň indeed, thank you. – Guillermo Moscoso Jan 20 '16 at 17:23
  • @JanTuroň Also note that the `key` should be decoded before the check for `[` because the this character itself can be encoded. – Pablo Oct 06 '17 at 18:41
  • @Pablo I don't think so: in `item[%5Bx]`, the key needs to be decoded AFTER [ is detected, in `item%5Bx%5D` it means that item[x] is the key, not just [x]. – Jan Turoň Oct 06 '17 at 19:45
  • @JanTuroň Any server that parses array from URL parameters will parse `item%5Bx%5D` as `item = [x]` https://i.imgur.com/bdS9vJ6.png – Pablo Oct 07 '17 at 17:11
  • @Pablo then you have to double encode it as `%255Bx%255D`, if it is the server's feature to auto-decode it. AFAIK there is no standard that the server MUST or SHOULD do it, but if you know any, please give me a link to include this note to the answer. – Jan Turoň Oct 07 '17 at 19:02
  • @JanTuroň I was trying to adapt your answer to parse the the output of `jQuery.serialize` which URL encodes the parameter names in that fashion: `item%5Bx%5D`. Demo: http://jsbin.com/holiduruji/edit?html,js,output – Pablo Oct 07 '17 at 23:27
35

You could get a JavaScript object containing the parameters with something like this:

var regex = /[?&]([^=#]+)=([^&#]*)/g,
    url = window.location.href,
    params = {},
    match;
while(match = regex.exec(url)) {
    params[match[1]] = match[2];
}

The regular expression could quite likely be improved. It simply looks for name-value pairs, separated by = characters, and pairs themselves separated by & characters (or an = character for the first one). For your example, the above would result in:

{v: "123", p: "hello"}

Here's a working example.

Robin Whittleton
  • 6,159
  • 4
  • 40
  • 67
James Allardice
  • 164,175
  • 21
  • 332
  • 312
  • why not use window.location.getParameter? – codeAnand Dec 13 '11 at 08:28
  • Your example does not return an object (it returns 2 strings), and it requires you to know the names of the parameters beforehand, which given what the OP is trying to do, is unlikely to be the case. Also, where is the documentation for `getParameter`? – James Allardice Dec 13 '11 at 08:33
  • 5
    The param name is technically `[^=#&]+` rather than just `[^=#]+` -- having a name without a value is legal and common. Also make sure that both the name and value are decoded: `params[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);` – AndrewF Oct 02 '15 at 17:53