是否有一种通过jQuery(或不使用)检索查询字符串值的无插件方法?
如果是,怎么办?如果没有,是否有插件可以这样做?
是否有一种通过jQuery(或不使用)检索查询字符串值的无插件方法?
如果是,怎么办?如果没有,是否有插件可以这样做?
当前回答
tl;博士
一个快速、完整的解决方案,可处理多值键和编码字符。
// using ES5 (200 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)})
// as a function with reduce
function getQueryParams() {
return location.search
? location.search.substr(1).split`&`.reduce((qd, item) => {let [k,v] = item.split`=`; v = v && decodeURIComponent(v); (qd[k] = qd[k] || []).push(v); return qd}, {})
: {}
}
多行:
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解构赋值、箭头函数、模板字符串####示例:
"?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"
阅读更多。。。关于Vanilla JavaScript解决方案。
要访问URL的不同部分,请使用位置。(搜索|哈希)
最简单(虚拟)解决方案
var queryDict = {};
location.search.substr(1).split("&").forEach(function(item) {queryDict[item.split("=")[0]] = item.split("=")[1]})
正确处理空钥匙。使用找到的最后一个值覆盖多键。
"?a=1&b=0&c=3&d&e&a=5"
> queryDict
a: "5"
b: "0"
c: "3"
d: undefined
e: undefined
多值键
简单的密钥检查(字典中的项目)?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", "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"]
v = v && decodeURIComponent(v);
if (location.search) location.search.substr(1).split("&").forEach(...)
其他回答
我使用这里列出的技术开发了一个小型库,以创建一个易于使用的解决方案;可以在这里找到:
https://github.com/Nijikokun/query-js
用法
正在获取特定参数/密钥:
query.get('param');
使用生成器获取整个对象:
var storage = query.build();
console.log(storage.param);
还有很多。。。查看github链接以获取更多示例。
特征
解码和参数缓存支持哈希查询字符串#hello?第3页支持传递自定义查询支持数组/对象参数user[]=“jim”&user[]=”bob“支持空管理&&支持不带值的声明参数name&hello=“world”支持重复参数param=1¶m=2干净、紧凑、可读的源4kbAMD,需要,节点支持
从MDN:
function loadPageVar (sVar) {
return unescape(window.location.search.replace(new RegExp("^(?:.*[&\\?]" + escape(sVar).replace(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1"));
}
alert(loadPageVar("name"));
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];
}
}
}
假设URL为
http://example.com/?stringtext=jquery&stringword=jquerybyexample
var tech = GetQueryStringParams('stringtext');
var blog = GetQueryStringParams('stringword');
这是我在GitHub上的查询字符串解析代码版本。
它的前缀是jquery.*,但解析函数本身不使用jquery。它非常快,但仍然可以进行一些简单的性能优化。
它还支持URL中的列表和哈希表编码,例如:
arr[]=10&arr[]=20&arr[]=100
or
hash[key1]=hello&hash[key2]=moto&a=How%20are%20you
jQuery.toQueryParams = function(str, separator) {
separator = separator || '&'
var obj = {}
if (str.length == 0)
return obj
var c = str.substr(0,1)
var s = c=='?' || c=='#' ? str.substr(1) : str;
var a = s.split(separator)
for (var i=0; i<a.length; i++) {
var p = a[i].indexOf('=')
if (p < 0) {
obj[a[i]] = ''
continue
}
var k = decodeURIComponent(a[i].substr(0,p)),
v = decodeURIComponent(a[i].substr(p+1))
var bps = k.indexOf('[')
if (bps < 0) {
obj[k] = v
continue;
}
var bpe = k.substr(bps+1).indexOf(']')
if (bpe < 0) {
obj[k] = v
continue;
}
var bpv = k.substr(bps+1, bps+bpe-1)
var k = k.substr(0,bps)
if (bpv.length <= 0) {
if (typeof(obj[k]) != 'object') obj[k] = []
obj[k].push(v)
} else {
if (typeof(obj[k]) != 'object') obj[k] = {}
obj[k][bpv] = v
}
}
return obj;
}
这里发布的一些解决方案效率低下。每次脚本需要访问参数时重复正则表达式搜索是完全不必要的,一个函数将参数拆分为关联数组样式对象就足够了。如果您不使用HTML5历史API,则每次加载页面只需要一次。这里的其他建议也无法正确解码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]);
})();
示例查询字符串:
?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
这也可以很容易地改进为处理数组样式的查询字符串。这里有一个这样的例子,但由于RFC 3986中没有定义数组样式参数,所以我不会用源代码污染这个答案。对于那些对“污染”版本感兴趣的人,请看下面坎贝尔的答案。
此外,正如评论中指出的;是key=value对的合法分隔符。它需要更复杂的正则表达式来处理;或&,我认为这是不必要的,因为这很少见;我想说,更不可能两者都使用。如果您需要支持;而不是&,只是在正则表达式中交换它们。
<script>var urlParams = <?php echo json_encode($_GET, JSON_HEX_TAG);?>;</script>
简单多了!
#已更新
一个新的功能是检索重复的参数,如下myparam=1和myparam=2。然而,没有一个规范,目前的大多数方法都遵循数组的生成。
myparam = ["1", "2"]
因此,这是管理它的方法:
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]);
}
}
})();