将光标移到/点击文章中的句子上,可以查看译文。      显示繁体中文内容    显示简体中文内容

How can I get query string values in JavaScript?
在JavaScript如何获取查询的字符串值?

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?

时间:

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


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

Usage :


var prodId = getParameterByName('prodId');

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!

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

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/

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'

Roshambo on snipplr.com has a really hot and 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 callvar langval = $.urlParam('lang');, and you've got it.

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

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.

Here's my stab at making Andy E's excellent solution into a full fledged jQuery plugin :


;(function ($) {
 $.extend({ 
 getQueryString: function (name) { 
 function parseParams() {
 var params = {},
 e,
 a =/+/g,//Regex for replacing addition symbol with a space
 r =/([^&=]+)=?([^&]*)/g,
 d = function (s) { return decodeURIComponent(s.replace(a,"")); },
 q = window.location.search.substring(1);

 while (e = r.exec(q))
 params[d(e[1])] = d(e[2]);

 return params;
 }

 if (!this.queryStringParams)
 this.queryStringParams = parseParams(); 

 return this.queryStringParams[name];
 }
 });
})(jQuery);

The syntax is :


var someVar = $.getQueryString('myParam');

Best of both worlds!

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.

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&car%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] bydecodeURIComponent(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&car%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"]

...