How can I get query string values in JavaScript?
How can I get query string values in JavaScript?
Question
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?
Accepted Answer
Update: Sep-2018
You can use URLSearchParams which is simple and has decent (but not complete) browser support.
const urlParams = new URLSearchParams(window.location.search);
const myParam = urlParams.get('myParam');
PS
Unfortunately URLSearchParams don't properly parse query strings with string keyed values. You might want to try locutus/parse_str
console.log(new URLSearchParams('a=b&c=d').toString()); // a=b&c=d
console.log(new URLSearchParams('a=b&c=d').get('a')); // b
console.log(new URLSearchParams('filters[a]=b&filters[c]=d').toString()); // filters%5Ba%5D=b&filters%5Bc%5D=d
console.log(new URLSearchParams('filters[a]=b&filters[c]=d').get('filters')); // null
Original
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](https://stackoverflow.com/questions/1746507/authoritative-position-of-duplicate-http-get-query-keys). NOTE: The function is case-sensitive. If you prefer case-insensitive parameter name, [add 'i' modifier to RegExp][2]
This is an update based on the new URLSearchParams specs to achieve the same result more succinctly. See answer titled "URLSearchParams" below.
Popular Answer
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!
UPDATED
A new capability would be to retrieve repeated params as following
myparam=1&myparam=2
. There is not a specification, however, most of the current approaches follow the generation of an array.
myparam = ["1", "2"]
So, this is the approach to manage it:
let urlParams = {};
(window.onpopstate = function () {
let 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)) {
if (decode(match[1]) in urlParams) {
if (!Array.isArray(urlParams[decode(match[1])])) {
urlParams[decode(match[1])] = [urlParams[decode(match[1])]];
}
urlParams[decode(match[1])].push(decode(match[2]));
} else {
urlParams[decode(match[1])] = decode(match[2]);
}
}
})();
Read more… Read less…
ES2015 (ES6)
getQueryStringParams = query => {
return query
? (/^[?#]/.test(query) ? query.slice(1) : query)
.split('&')
.reduce((params, param) => {
let [key, value] = param.split('=');
params[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : '';
return params;
}, {}
)
: {}
};
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. It does not work because some variables are undefined.
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 then they store the value of d
, otherwise they 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(paramsArray) {
let params = {};
for (let i = 0; i < paramsArray.length; ++i)
{
let param = paramsArray[i]
.split('=', 2);
if (param.length !== 2)
continue;
params[param[0]] = decodeURIComponent(param[1].replace(/\+/g, " "));
}
return params;
})(window.location.search.substr(1).split('&'))
})(jQuery);
Usage
//Get a param
$.QueryString.param
//-or-
$.QueryString["param"]
//This outputs something like...
//"val"
//Get all params as object
$.QueryString
//This outputs something like...
//Object { param: "val", param2: "val" }
//Set a param (only in the $.QueryString object, doesn't affect the browser's querystring)
$.QueryString.param = "newvalue"
//This doesn't output anything, it just updates the $.QueryString object
//Convert object into string suitable for url a querystring (Requires jQuery)
$.param($.QueryString)
//This outputs something like...
//"param=newvalue¶m2=val"
//Update the url/querystring in the browser's location bar with the $.QueryString object
history.replaceState({}, '', "?" + $.param($.QueryString));
//-or-
history.pushState({}, '', "?" + $.param($.QueryString));
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
Improved version of Artem Barger's answer:
function getParameterByName(name) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
For more information on improvement see: http://james.padolsey.com/javascript/bujs-1-getparameterbyname/
URLSearchParams
Firefox 44+, Opera 36+, Edge 17+, Safari 10.3+ and Chrome 49+ support the URLSearchParams API:
There is a google-suggested URLSearchParams polyfill for the stable versions of IE.
It is not standardized by W3C, but it is a living standard by WhatWG.
You can use it on location
:
let params = new URLSearchParams(location.search);
or
let params = (new URL(location)).searchParams;
Or of course on any URL:
let url = new URL('https://example.com?foo=1&bar=2');
let params = new URLSearchParams(url.search);
You can get params also using a shorthand .searchParams
property on the URL object, like this:
let params = new URL('https://example.com?foo=1&bar=2').searchParams;
params.get('foo'); // "1"
params.get('bar'); // "2"
You read/set parameters through the get(KEY)
, set(KEY, VALUE)
, append(KEY, VALUE)
API. You can also iterate over all values for (let p of params) {}
.
A reference implementation and a sample page are available for auditing and testing.
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'
However, as of Nov 11, 2014, Purl is no longer maintained and the author recommends using URI.js instead. The jQuery plugin is different in that it focuses on elements - for usage with strings, just use URI
directly, with or without jQuery. Similar code would look as such, fuller docs here:
var url = new URI('http://allmarkedup.com/folder/dir/index.html?item=value'); // plain JS version
url.protocol(); // returns 'http'
url.path(); // returns '/folder/dir/index.html'
tl;dr
A quick, complete solution, which handles multivalued keys and encoded characters.
var qd = {};
if (location.search) location.search.substr(1).split("&").forEach(function(item) {var s = item.split("="), k = s[0], v = s[1] && decodeURIComponent(s[1]); (qd[k] = qd[k] || []).push(v)})
//using ES6 (23 characters cooler)
var qd = {};
if (location.search) location.search.substr(1).split`&`.forEach(item => {let [k,v] = item.split`=`; v = v && decodeURIComponent(v); (qd[k] = qd[k] || []).push(v)})
Multi-lined:
var qd = {};
if (location.search) location.search.substr(1).split("&").forEach(function(item) {
var s = item.split("="),
k = s[0],
v = s[1] && decodeURIComponent(s[1]); // null-coalescing / short-circuit
//(k in qd) ? qd[k].push(v) : qd[k] = [v]
(qd[k] = qd[k] || []).push(v) // null-coalescing / short-circuit
})
What is all this code...
"null-coalescing", short-circuit evaluation
ES6 Destructuring assignments, Arrow functions, Template strings
"?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 a 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]
orqd[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"]
From comments
*!!! 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);
If the querystring is empty (location.search == ""
), the result is somewhat misleading qd == {"": undefined}
. It is suggested to check the querystring before launching the parsing function likeso:
if (location.search) location.search.substr(1).split("&").forEach(...)