我怎样才能在JavaScript中查询string值?
有没有插件,通过jQuery(或没有)检索查询string值的方式?
如果是这样,怎么样? 如果没有,是否有插件可以这样做?
你不需要为此目的的jQuery。 你可以使用一些纯粹的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, " ")); }
用法:
// 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)
注意:如果一个参数存在几次( ?foo=lorem&foo=ipsum
),您将得到第一个值( lorem
)。 有没有关于这个标准和用法不同,请参阅这个问题: 重复HTTP GET查询键的权威性位置 。
这是基于新的URLSearchParams规范的更新,可以更简洁地达到相同的结果。 请参阅下面的“ URLSearchParams ”。
这里发布的一些解决scheme效率不高。 每次脚本需要访问参数时重复正则expression式search是完全没有必要的,将参数拆分成关联数组样式对象的单个函数就足够了。 如果您不使用HTML 5 History API,则每个页面加载仅需要一次。 这里的其他build议也无法正确解码URL。
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]); })();
查询string示例:
?i=main&mode=front&sid=de8d49b78a85a322c4155015fdce22c4&enc=+Hello%20&empty
结果:
urlParams = { enc: " Hello ", i: "main", mode: "front", sid: "de8d49b78a85a322c4155015fdce22c4", empty: "" } alert(urlParams["mode"]); // -> "front" alert("empty" in urlParams); // -> true
这也可以很容易地改善处理数组式的查询string。 这里有一个例子,但是由于在RFC 3986中没有定义数组样式的参数,我不会用源代码来污染这个答案。 对于那些对“污染”版本感兴趣的人,请看下面的campbeln答案 。
另外,正如评论中指出的那样;
是key=value
对的合法分隔符。 这将需要一个更复杂的正则expression式来处理;
或者,我认为这是不必要的,因为这很less见;
被使用,我会说更不可能这两个将被使用。 如果你需要支持;
而不是&
,只是在正则expression式中交换它们。
如果您使用的是服务器端预处理语言,则可能需要使用其本机JSON函数为您完成繁重的工作。 例如,在PHP中,你可以写:
<script>var urlParams = <?php echo json_encode ($_GET, JSON_HEX_TAG);?>;</script>
简单得多!
ES2015(ES6)
const getParams = query => { if (!query) { return { }; } return (/^[?#]/.test(query) ? query.slice(1) : query) .split('&') .reduce((params, param) => { let [ key, value ] = param.split('='); params[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : ''; return params; }, { }); };
没有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('&'));
使用类似于?topic=123&name=query+string
的URL,将返回以下内容:
qs["topic"]; // 123 qs["name"]; // query string qs["nothere"]; // undefined (object)
Google方法
撕毁Google的代码,我发现他们使用的方法: 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 }
它被混淆了,但这是可以理解的。
他们开始寻找从URL的参数?
并从哈希#
。 然后,对于每个参数,他们在等号b[f][p]("=")
(它们看起来像indexOf
,它们使用char的位置来获取键/值)分割。 有了它,他们检查参数是否有值,如果它有存储的价值,如果没有它只是继续。
最后返回对象d
,处理转义和+
符号。 这个对象就像我的一样,它有相同的行为。
我的方法作为一个jQuery插件
(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);
用法
//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));
性能testing(针对正则expression式分割方法) ( jsPerf )
准备代码:方法声明
分割testing代码
var qs = window.GetQueryString(query); var search = qs["q"]; var value = qs["value"]; var undef = qs["undefinedstring"];
正则expression式testing代码
var search = window.getParameterByName("q"); var value = window.getParameterByName("value"); var undef = window.getParameterByName("undefinedstring");
在Windows Server 2008 R2 / 7 x64上的Firefox 4.0 x86中进行testing
- 拆分法 :最快144,780±2.17%
- 正则expression式 :13,891±0.85%| 慢了90%
Artem Barger的回答改进版本:
function getParameterByName(name) { var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search); return match && decodeURIComponent(match[1].replace(/\+/g, ' ')); }
有关改进的更多信息,请参阅: http : //james.padolsey.com/javascript/bujs-1-getparameterbyname/
只是另一个build议。 插件Purl允许检索URL的所有部分,包括锚点,主机等。
它可以使用或不使用jQuery。
用法很简单,很酷:
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'
不过,截至2014年11月11日,Purl已不再维护,作者推荐使用URI.js。 jQuery插件的不同之处在于它专注于元素 – 与string一起使用,直接使用URI
,无论是否使用jQuery。 类似的代码看起来像这样,更完整的文档在这里 :
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'
URLSearchParams
Firefox 44+,Opera 36+和Chrome 49+支持URLSearchParams API:
- Chrome公告和详细信息
- 歌剧公告和细节
- Firefox公告和详细信息
Safari Nightly已经实现了它,它也在为Microsoft Edge开发。 有一个谷歌build议的URLSearchParams填充 Safari,Edge和IE的稳定版本。
W3C没有标准化,但它是WhatWG的生活标准。
你可以使用它的位置,但你需要删除?
问号(例如,使用.slice(1)
):
let params = new URLSearchParams(location.search.slice(1));
要么
let params = (new URL(location)).searchParams;
或者当然在任何url:
let url = new URL('https://example.com?foo=1&bar=2'); let params = new URLSearchParams(url.search.slice(1));
你也可以在URL对象上使用简单的.searchParams
属性来获得参数,如下所示:
let params = new URL('https://example.com?foo=1&bar=2').searchParams; params.get('foo'); // "1" params.get('bar'); // "2"
您通过get(KEY)
, set(KEY, VALUE)
, append(KEY, VALUE)
API读取/设置参数。 你也可以遍历所有的值for (let p of params) {}
。
参考实现和样本页面可用于审计和testing。
snipplr.com上的Roshambo有一个简单的脚本来实现这个function 改进 。 用他的脚本,你也可以很容易地取出你想要的参数。
要点是:
$.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; }
然后从查询string中获取参数。
所以如果URL /查询string是xyz.com/index.html?lang=de
。
只需调用var langval = $.urlParam('lang');
,你已经掌握了。
UZBEKJON还有一个很棒的博客文章, 使用jQuery获取URL参数和值 。
TL;博士
一个快速, 完整的解决scheme ,处理多值键和编码字符 。
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)})
多行:
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 })
这是什么代码…
“零合并” , 短路评估
ES6解构赋值 , 箭头函数 , 模板string
例:
"?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", "text"] 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"
阅读更多…关于Vanilla JavaScript解决scheme。
访问URL使用location.(search|hash)
不同部分location.(search|hash)
最简单的(虚拟)解决scheme
var queryDict = {}; location.search.substr(1).split("&").forEach(function(item) {queryDict[item.split("=")[0]] = item.split("=")[1]})
- 正确处理空键 。
- 用find的最后一个值覆盖多个键 。
"?a=1&b=0&c=3&d&e&a=5" > queryDict a: "5" b: "0" c: "3" d: undefined e: undefined
多值键
简单的键检查(item in dict) ? dict.item.push(val) : dict.item = [val]
(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]]})
- 现在返回数组 。
- 通过
qd.key[index]
或qd[key][index]
访问值
> qd a: ["1", "5"] b: ["0"] c: ["3"] d: [undefined] e: [undefined]
编码的字符?
使用decodeURIComponent()
作为第二个或两个拆分。
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]})
例:
"?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", "text"] b: ["0"] c: ["3"] d: ["undefined"] // decodeURIComponent(undefined) returns "undefined" !!!* e: ["undefined", "http://w3schools.com/my test.asp?name=ståle&car=saab"]
从评论
*! 请注意, decodeURIComponent(undefined)
返回string"undefined"
。 解决方法就是使用&&
,这样可以确保decodeURIComponent()
不会在未定义的值上被调用。 (请参阅顶部的“完整解决scheme”。)
v = v && decodeURIComponent(v);
如果查询string是空的( location.search == ""
),结果有点误导qd == {"": undefined}
。 build议在启动parsing函数之前检查查询string:
if (location.search) location.search.substr(1).split("&").forEach(...)
如果你使用jQuery,你可以使用一个库,比如jQuery BBQ:后退button和查询库 。
jQuery BBQ提供了一个完整的
.deparam()
方法,以及散列状态pipe理和片段/查询string分析和合并实用程序方法。
编辑:添加Deparam示例:
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(); } };
这里是我的意思是让Andy E成为一个完整的jQuery插件的绝佳解决scheme:
;(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);
语法是:
var someVar = $.getQueryString('myParam');
两全其美!
只需使用两个分割 :
function get(n) { var half = location.search.split(n + '=')[1]; return half !== undefined ? decodeURIComponent(half.split('&')[0]) : null; }
我正在阅读所有以前和更完整的答案。 但我认为这是最简单快捷的方法。 你可以检查这个jsPerf 基准
要解决Rup的注释中的问题,请将第一行更改为下面的两行来添加条件分割。 但绝对精度意味着它现在比正则expression式更慢(请参阅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; }
所以如果你知道你不会遇到Rup的反案例,那就赢了。 否则,正则expression式。
或者,如果你有查询string的控制,并可以保证你试图得到一个值将永远不会包含任何URL编码的字符(这些在一个值是一个坏主意) – 你可以使用以下更简单和可读的版本第一个选项:
function getQueryStringValueByName(name) { var queryStringFromStartOfValue = location.search.split(name + '=')[1]; return queryStringFromStartOfValue !== undefined ? queryStringFromStartOfValue.split('&')[0] : null;
如果你在做更多的URL操作而不是简单地parsing查询string,你可能会发现URI.js有帮助。 这是一个操纵url的图书馆 – 并附带所有的花里胡哨的东西。 (对不起,在这里自我广告)
把你的查询string转换成地图:
var data = URI('?foo=bar&bar=baz&foo=world').query(true); data == { "foo": ["bar", "world"], "bar": "baz" }
(URI.js也“修复”坏string,比如?&foo&&bar=baz&
to ?foo&bar=baz
)
我喜欢Ryan Phelan的解决scheme 。 但我没有看到任何扩展jQuery的点? 没有使用jQuery的function。
另一方面,我喜欢Google Chrome中的内置function:window.location.getParameter。
那么为什么不使用这个? 好的,其他浏览器没有。 所以让我们创build这个函数,如果它不存在:
if (!window.location.getParameter ) { window.location.getParameter = function(key) { 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[key]; }; }
这个函数或多或less来自Ryan Phelan,但是它的包装方式不同:清晰的名称和其他JavaScript库的依赖关系。 更多关于这个function在我的博客 。
这是获取类似于PHP $ _GET数组的对象的一种快速方法:
function get_query(){ var url = location.search; var qs = url.substring(url.indexOf('?') + 1).split('&'); for(var i = 0, result = {}; i < qs.length; i++){ qs[i] = qs[i].split('='); result[qs[i][0]] = decodeURIComponent(qs[i][1]); } return result; }
用法:
var $_GET = get_query();
对于查询stringx=5&y&z=hello&x=6
这将返回对象:
{ x: "6", y: undefined, z: "hello" }
用简单的JavaScript代码保持简单:
function qs(key) { 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[key]; }
在JavaScript代码中的任何地方调用它:
var result = qs('someKey');
这些都是很好的答案,但是我需要一些更强大的东西,并且认为你们都可能喜欢我所创造的东西。
这是一个简单的库方法,可以parsing和处理URL参数。 静态方法具有以下可以在主题URL上调用的子方法:
- 和getHost
- 的getPath
- getHash
- setHash
- getParams
- getQuery
- setParam
- getParam
- hasParam
- removeParam
例:
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 the first parameter url = URLParser(url).removeParam('myparam1'); document.write(url + ' - Remove the first parameter<br>'); // Add a third parameter url = URLParser(url).setParam('myparam3',3); document.write(url + ' - Add a third parameter<br>'); // Remove the second parameter url = URLParser(url).removeParam('myparam2'); document.write(url + ' - Remove the second parameter<br>'); // Add a hash url = URLParser(url).setHash('newhash'); document.write(url + ' - Set Hash<br>'); // Remove the last parameter url = URLParser(url).removeParam('myparam3'); document.write(url + ' - Remove the last parameter<br>'); // Remove a parameter that doesn't exist url = URLParser(url).removeParam('myparam3'); document.write(url + ' - Remove a parameter that doesn\"t exist<br>');
From the MDN :
function loadPageVar (sVar) { return unescape(window.location.search.replace(new RegExp("^(?:.*[&\\?]" + escape(sVar).replace(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1")); } alert(loadPageVar("name"));
I use regular expressions a lot, but not for that.
It seems easier and more efficient to me to read the query string once in my application, and build an object from all the key/value pairs like:
var search = function() { var s = window.location.search.substr(1), p = s.split(/\&/), l = p.length, kv, r = {}; if (l === 0) {return false;} while (l--) { kv = p[l].split(/\=/); r[kv[0]] = decodeURIComponent(kv[1] || '') || true; } return r; }();
For a URL like http://domain.com?param1=val1¶m2=val2
you can get their value later in your code as search.param1
and search.param2
.
Code golf:
var a = location.search&&location.search.substr(1).replace(/\+/gi," ").split("&"); for (var i in a) { var s = a[i].split("="); a[i] = a[unescape(s[0])] = unescape(s[1]); }
Display it!
for (i in a) { document.write(i + ":" + a[i] + "<br/>"); };
On my Mac: test.htm?i=can&has=cheezburger
displays
0:can 1:cheezburger i:can has:cheezburger
function GET() { var data = []; for(x = 0; x < arguments.length; ++x) data.push(location.href.match(new RegExp("/\?".concat(arguments[x],"=","([^\n&]*)")))[1]) return data; } example: data = GET("id","name","foo"); query string : ?id=3&name=jet&foo=b returns: data[0] // 3 data[1] // jet data[2] // b or alert(GET("id")[0]) // return 3
Roshambo jQuery method wasn't taking care of decode URL
http://snipplr.com/view/26662/get-url-parameters-with-jquery–improved/
Just added that capability also while adding in the return statement
return decodeURIComponent(results[1].replace(/\+/g, " ")) || 0;
Now you can find the updated gist:
$.urlParam = function(name){ var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href); if (!results) { return 0; } return decodeURIComponent(results[1].replace(/\+/g, " ")) || 0; }
I like this one (taken from jquery-howto.blogspot.co.uk):
// get an array with all querystring values // example: var valor = getUrlVars()["valor"]; function getUrlVars() { 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; }
对我很好。
Here's my edit to this excellent answer – with added ability to parse query strings with keys without values.
var url = 'http://sb.com/reg/step1?param'; 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[1]) p[1] = decodeURIComponent(p[1].replace(/\+/g, " ")); b[p[0]] = p[1]; } return b; })((url.split('?'))[1].split('&'));
IMPORTANT! The parameter for that function in the last line is different. It's just an example of how one can pass an arbitrary URL to it. You can use last line from Bruno's answer to parse the current URL.
So what exactly changed? With url http://sb.com/reg/step1?param=
results will be same. But with url http://sb.com/reg/step1?param
Bruno's solution returns an object without keys, while mine returns an object with key param
and undefined
value.
I needed an object from the query string, and I hate lots of code. It 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'}
This is a function I created a while back and I'm quite happy with. It is not case sensitive – which is handy. Also, if the requested QS doesn't exist, it just returns an empty string.
I use a compressed version of this. I'm posting uncompressed for the novice types to better explain what's going on.
I'm sure this could be optimized or done differently to work faster, but it's always worked great for what I need.
请享用。
function getQSP(sName, sURL) { var theItmToRtn = ""; var theSrchStrg = location.search; if (sURL) theSrchStrg = sURL; var sOrig = theSrchStrg; theSrchStrg = theSrchStrg.toUpperCase(); sName = sName.toUpperCase(); theSrchStrg = theSrchStrg.replace("?", "&") theSrchStrg = theSrchStrg + "&"; var theSrchToken = "&" + sName + "="; if (theSrchStrg.indexOf(theSrchToken) != -1) { var theSrchTokenLth = theSrchToken.length; var theSrchTokenLocStart = theSrchStrg.indexOf(theSrchToken) + theSrchTokenLth; var theLocOfNextAndSign = theSrchStrg.indexOf("&", theSrchTokenLocStart); theItmToRtn = unescape(sOrig.substring(theSrchTokenLocStart, theLocOfNextAndSign)); } return unescape(theItmToRtn); }
Here's an extended version of Andy E's linked "Handle array-style query strings"-version. Fixed a bug ( ?key=1&key[]=2&key[]=3
; 1
is lost and replaced with [2,3]
), made a few minor performance improvements (re-decoding of values, recalculating "[" position, etc.) and added a number of improvements (functionalized, support for ?key=1&key=2
, support for ;
delimiters). I left the variables annoyingly short, but added comments galore to make them readable (oh, and I reused v
within the local functions, sorry if that is confusing ;).
It will handle the following querystring…
?test=Hello&person=neek&person[]=jeff&person[]=jim&person[extra]=john&test3&nocache=1398914891264
…making it into an object that looks like…
{ "test": "Hello", "person": { "0": "neek", "1": "jeff", "2": "jim", "length": 3, "extra": "john" }, "test3": "", "nocache": "1398914891264" }
As you can see above, this version handles some measure of "malformed" arrays, ie – person=neek&person[]=jeff&person[]=jim
or person=neek&person=jeff&person=jim
as the key is identifiable and valid (at least in dotNet's NameValueCollection.Add ):
If the specified key already exists in the target NameValueCollection instance, the specified value is added to the existing comma-separated list of values in the form "value1,value2,value3".
It seems the jury is somewhat out on repeated keys as there is no spec. In this case, multiple keys are stored as an (fake)array. But do note that I do not process values based on commas into arrays.
The code:
getQueryStringKey = function(key) { return getQueryStringAsObject()[key]; }; getQueryStringAsObject = function() { var b, cv, e, k, ma, sk, v, r = {}, d = function (v) { return decodeURIComponent(v).replace(/\+/g, " "); }, //# d(ecode) the v(alue) q = window.location.search.substring(1), //# suggested: q = decodeURIComponent(window.location.search.substring(1)), s = /([^&;=]+)=?([^&;]*)/g //# original regex that does not allow for ; as a delimiter: /([^&=]+)=?([^&]*)/g ; //# ma(make array) out of the v(alue) ma = function(v) { //# If the passed v(alue) hasn't been setup as an object if (typeof v != "object") { //# Grab the cv(current value) then setup the v(alue) as an object cv = v; v = {}; v.length = 0; //# If there was a cv(current value), .push it into the new v(alue)'s array //# NOTE: This may or may not be 100% logical to do... but it's better than loosing the original value if (cv) { Array.prototype.push.call(v, cv); } } return v; }; //# While we still have key-value e(ntries) from the q(uerystring) via the s(earch regex)... while (e = s.exec(q)) { //# while((e = s.exec(q)) !== null) { //# Collect the open b(racket) location (if any) then set the d(ecoded) v(alue) from the above split key-value e(ntry) b = e[1].indexOf("["); v = d(e[2]); //# As long as this is NOT a hash[]-style key-value e(ntry) if (b < 0) { //# b == "-1" //# d(ecode) the simple k(ey) k = d(e[1]); //# If the k(ey) already exists if (r[k]) { //# ma(make array) out of the k(ey) then .push the v(alue) into the k(ey)'s array in the r(eturn value) r[k] = ma(r[k]); Array.prototype.push.call(r[k], v); } //# Else this is a new k(ey), so just add the k(ey)/v(alue) into the r(eturn value) else { r[k] = v; } } //# Else we've got ourselves a hash[]-style key-value e(ntry) else { //# Collect the d(ecoded) k(ey) and the d(ecoded) sk(sub-key) based on the b(racket) locations k = d(e[1].slice(0, b)); sk = d(e[1].slice(b + 1, e[1].indexOf("]", b))); //# ma(make array) out of the k(ey) r[k] = ma(r[k]); //# If we have a sk(sub-key), plug the v(alue) into it if (sk) { r[k][sk] = v; } //# Else .push the v(alue) into the k(ey)'s array else { Array.prototype.push.call(r[k], v); } } } //# Return the r(eturn value) return r; };
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.
The problem with the top answer on that question is that it's not-supported parameters placed after #, but sometimes it's needed to get this value also.
I modified the answer to let it parse a full query string with a 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; };
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');
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
用法
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.
特征
- Caching on both decoding and parameters
- Supports hash query strings
#hello?page=3
- Supports passing custom queries
- Supports Array / Object Parameters
user[]="jim"&user[]="bob"
- Supports empty management
&&
- Supports declaration parameters without values
name&hello="world"
- Supports repeated parameters
param=1¶m=2
- Clean, compact, and readable source
4kb
- AMD, Require, Node support