如何在JavaScript中获取查询字符串的值?

2694

有没有一种无需插件的方式,可以通过jQuery(或者不使用jQuery)来获取查询字符串的值?

如果有,该如何实现?如果没有,是否有插件可以实现这个功能?


我使用在 jQuery-Plugin – getUrlParam (version 2) 中描述的插件 getUrlParam - coma
我喜欢Dojo的queryToObject。如果你在节食,这个函数可以轻松地从框架中提取出来。 - hurrymaplelad
69
一个纯 JavaScript 的解决方案,不使用正则表达式:http://css-tricks.com/snippets/javascript/get-url-variables/ - Lorenzo Polidori
6
尽管对这个问题的顶级解决方案由于其出色的观察力指出了不需要使用jQuery而备受欢迎,但是它创建新的正则表达式并为每个所需参数重新解析查询字符串的方法极其低效。有更加高效(和通用)的解决方案存在已久,例如在此文章中再版的:http://www.htmlgoodies.com/beyond/javascript/article.php/11877_3755006_3/How-to-Use-a-JavaScript-Query-String-Parser.htm - Joseph Myers
1
可能是JavaScript查询字符串的重复问题。 - user456814
4
约瑟夫,“jQuery 不是必需品”的这一观点,当然它并非必须。jQuery所做的一切都可以使用JavaScript实现。人们使用jQuery是为了方便。jQuery的意义在于提供便利,而不是因为它能做比JavaScript更多的事情。 - Val Kornea
73个回答

24
在实际操作中查看:https://codepen.io/ajorpheus/pen/XWyWWNQ
http://someurl.com?key=value&keynovalue&keyemptyvalue=&&keynovalue=nowhasvalue#somehash
  • 常规的键/值对(?param=value
  • 没有值的键(?param:没有等号或值)
  • 带有空值的键(?param=:有等号,但等号右边没有值)
  • 重复的键(?param=1&param=2
  • 删除空键(?&&:没有键或值)

###代码:

-

    var queryString = window.location.search || '';
    var keyValPairs = [];
    var params      = {};
    queryString     = queryString.substr(1);

    if (queryString.length)
    {
       keyValPairs = queryString.split('&');
       for (pairNum in keyValPairs)
       {
          var key = keyValPairs[pairNum].split('=')[0];
          if (!key.length) continue;
          if (typeof params[key] === 'undefined')
             params[key] = [];
          params[key].push(keyValPairs[pairNum].split('=')[1]);
       }
    }

###如何拨打电话:

-

    params['key'];  // returns an array of values (1..n)

###输出:

-

    key            ["value"]
    keyemptyvalue  [""]
    keynovalue     [undefined, "nowhasvalue"]

23
这个很好用。其他答案中的正则表达式引入了不必要的开销。
function getQuerystring(key) {
    var query = window.location.search.substring(1);
    var vars = query.split("&");
    for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split("=");
        if (pair[0] == key) {
            return pair[1];
        }
    }
}

taken from here


3
在返回pair[1]之前,您可能至少希望调用decodeUriComponent对其进行解码,如果没有像其他解决方案一样先将加号替换为空格。其他一些解决方案还倾向于在拆分=时设置2个部分的限制,以更宽容地接受输入。 - Rup
1
@Rup 你说得对...实际上在我的代码中它总是一个数字而不是任何特殊字符,所以错过了... - IT ppl
谢谢!这是Kindle实验浏览器支持的唯一方法。这个项目有点疯狂! :·) - Roc Boronat

21
我使用此处列出的技术开发了一个小型库,以创建一个易于使用的、随时可用的解决方案;它可以在这里找到:

https://github.com/Nijikokun/query-js

用法

获取特定参数/键:

query.get('param');

使用builder获取整个对象:

var storage = query.build();
console.log(storage.param);

还有更多...请查看 GitHub 链接以获得更多示例。

特性

  1. 对解码和参数均支持缓存
  2. 支持哈希查询字符串 #hello?page=3
  3. 支持传递自定义查询
  4. 支持数组/对象参数 user[]="jim"&user[]="bob"
  5. 支持空值管理 &&
  6. 支持声明参数无值的情况 name&hello="world"
  7. 支持重复参数 param=1&param=2
  8. 源代码简洁、紧凑、易读 4kb
  9. 支持 AMD、Require 和 Node

20

获取查询的单行代码:

var value = location.search.match(new RegExp(key + "=(.*?)($|\&)", "i"))[1];

6
如果键不存在会触发错误,请尝试这个 (location.search.match(new RegExp('kiosk_modeasdf' + "=(.*?)($|\&)", "i")) || [])[1]。该代码的作用是检索 URL 中名为"kiosk_modeasdf"的参数值,如果该参数不存在,则返回undefined。 - Brad Koch
@Brad,当然是未定义的,因为那是你要查找的键。如果你的查询是?hello=world,var value = location.search.match(new RegExp("hello" + "=(.*?)($|\&)", "i"))[1]; 将返回 "world" - tim
2
@BradKoch 我发现你的解决方案最好,特别是使用短路到一个空字符串 (window.location.search.match(new RegExp('kiosk_modeasdf' + "=(.*?)($|&)", "i")) || [])[1] || ''; - rob
我认为你忘记测试以'?'或'&'开头的键了,例如: var result = location.search.match(new RegExp("[?&]" + key + "=(.*?)($|&)", "i")); - e-frank

18

这是我的查询字符串解析代码在GitHub上的版本

它以jquery.*为“前缀”,但解析函数本身不使用jQuery。它非常快,但仍可进行简单的性能优化。

此外,它还支持URL中列表和哈希表的编码,例如:

arr[]=10&arr[]=20&arr[]=100
或者
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;

}

很好,但它不能处理筛选器[主题] [] =列表的情况。 - brauliobo
嘿,如何使用上面的代码按键获取值?我想从此URL中获取城市值... http://abc.xyzl/urlpart1/urlpart2?city%5B0%5D=55&page=2&city[]=4&functionalarea[]=1&functionalarea[]=2 - Abhinav Gupta

18

我更倾向于使用split()而不是正则表达式进行此操作:

function getUrlParams() {
    var result = {};
    var params = (window.location.search.split('?')[1] || '').split('&');
    for(var param in params) {
        if (params.hasOwnProperty(param)) {
            var paramParts = params[param].split('=');
            result[paramParts[0]] = decodeURIComponent(paramParts[1] || "");
        }
    }
    return result;
}

我本来不想使用正则表达式,所以采用了这个解决方案。我发现它运行得非常好。谢谢! - dogonaroof

18
一个非常轻量级的jQuery方法:
var qs = window.location.search.replace('?','').split('&'),
    request = {};
$.each(qs, function(i,v) {
    var initial, pair = v.split('=');
    if(initial = request[pair[0]]){
        if(!$.isArray(initial)) {
            request[pair[0]] = [initial]
        }
        request[pair[0]].push(pair[1]);
    } else {
        request[pair[0]] = pair[1];
    }
    return;
});
console.log(request);

而要警告,例如?q

alert(request.q)

2
很好。已经有几个类似的答案了 - 都是通过拆分迭代 - 尽管没有使用jQuery的each,而且我认为它们中没有一个完美的。不过,我不理解你闭包中的return语句,而且我认为在读取这两个pair[]值时需要对它们进行decodeUriComponent解码。 - Rup
是的,使用decodeUriComponent绝对是最佳实践 - 我只是随意写了一下。至于返回...我只是保持习惯返回一些东西。完全没有必要。 - Roi

13

这是我正在使用的内容:

/**
 * Examples:
 * getUrlParams()['myparam']    // url defaults to the current page
 * getUrlParams(url)['myparam'] // url can be just a query string
 *
 * Results of calling `getUrlParams(url)['myparam']` with various urls:
 * example.com                               (undefined)
 * example.com?                              (undefined)
 * example.com?myparam                       (empty string)
 * example.com?myparam=                      (empty string)
 * example.com?myparam=0                     (the string '0')
 * example.com?myparam=0&myparam=override    (the string 'override')
 *
 * Origin: https://dev59.com/nHNA5IYBdhLWcg3wmfAa#23946023
 */
function getUrlParams (url) {
    var urlParams = {} // return value
    var queryString = getQueryString()
    if (queryString) {
        var keyValuePairs = queryString.split('&')
        for (var i = 0; i < keyValuePairs.length; i++) {
            var keyValuePair = keyValuePairs[i].split('=')
            var paramName = keyValuePair[0]
            var paramValue = keyValuePair[1] || ''
            urlParams[paramName] = decodeURIComponent(paramValue.replace(/\+/g, ' '))
        }
    }
    return urlParams // functions below
    function getQueryString () {
        var reducedUrl = url || window.location.search
        reducedUrl = reducedUrl.split('#')[0] // Discard fragment identifier.
        var queryString = reducedUrl.split('?')[1]
        if (!queryString) {
            if (reducedUrl.search('=') !== false) { // URL is a query string.
                queryString = reducedUrl
            }
        }
        return queryString
    } // getQueryString
} // getUrlParams

在最后一种情况下返回“override”而不是“0”,这使其与PHP保持一致。在IE7中运行。


1
这是因为每个人似乎都有不同的要求,例如处理没有值的键或通过构建值数组来处理重复的键等。已经有很多分裂的答案了,但我没有看到与这个完全相同的答案,确实如此。(顺便说一句,我认为paramName在技术上也需要进行decodeURIComponent,尽管我怀疑任何人都不会使用非平凡的参数。) - Rup
1
参数名称不应需要解码。 - Val Kornea
2
为什么不呢?HTML 5并没有限制输入控件名称的字符集,也不能保证它们来自HTML。我看不出为什么会有可打印字符的限制。 - Rup
1
这个解决方案很好,但为什么语句末尾没有分号? - Sudar
2
@Sudar 因为没有必要使用它们。大多数人总是包含它们,只是因为他们总是看到其他人包含它们,并且其他语言需要它们;通常它们被错误地认为在JavaScript中也是必需的,这有时会导致令人困惑的问题。没有理由地做事情通常是误导性的;JavaScript不是C++或PHP。查找“防御性分号”。 - Val Kornea
8
很惊讶这里发布了多少过于复杂和不完整的解决方案。哈哈,真是讽刺。 - NiCk Newman

10

对于想要一种简短方法(但有限制)的人:

location.search.split('myParameter=')[1]

4
这还不够通用:它假定1)你只关心单个参数2)保证它是在行中的最后一个参数(即你可以保证所有浏览器都会将其放在最后,或者它是页面上唯一的参数,而且你不会将URL放在RSS聚合器中,以免添加utm参数),并且3)值中没有任何可以转义传输的字符,例如空格或许多符号。 - Rup
2
没有一种适用于所有情况的方法。如果你有一个完美的一行代码解决方案,我会非常关注和倾听。上面是一个快速解决方案,不适用于一般情况,但适用于想要轻量级和快速实现的程序员。无论如何,感谢您的评论。 - George
2
(location.search.split('myParameter=')[1])。split('&') [0]; 这将在多个参数的情况下给您相同的结果。仍然只适用于静态实现。 - Anurag

10

获取所有查询字符串参数,包括复选框的值(数组)。

考虑到GET参数的正确和正常使用,我发现大多数函数缺少对数组的支持以及删除哈希数据。

因此,我编写了以下函数:

function qs(a){
 if(!a)return {};
 a=a.split('#')[0].split('&');
 var b=a.length,c={},d,k,v;
 while(b--){
  d=a[b].split('=');
  k=d[0].replace('[]',''),v=decodeURIComponent(d[1]||'');
  c[k]?typeof c[k]==='string'?(c[k]=[v,c[k]]):(c[k].unshift(v)):c[k]=v;
 }
 return c
}

使用简写运算符和 while-- 循环,性能应该非常好。

支持:

  1. 空值(key= / key
  2. 键值对(key=value
  3. 数组(key[]=value
  4. 哈希表(哈希标签已拆分出来

注意:

不支持对象数组(key[key]=value)

如果空格是 +,它将保留为 +。

如果需要,请添加 .replace(/\+/g, " ")

用法:

qs('array[]=1&array[]=2&key=value&empty=&empty2#hash')

返回:

{
    "empty": "",
    "key": "value",
    "array": [
        "1",
        "2"
    ]
}

演示:

http://jsfiddle.net/ZQMrt/1/

信息

如果您不理解某些内容或无法阅读该函数,请询问。我很乐意解释我在这里做了什么。

如果您认为该函数不可读性和可维护性差,我可以为您重写该函数,但请考虑使用简写和位运算符始终比标准语法更快(也许阅读 ECMA-262 书中的简写和位运算符,或使用您喜欢的搜索引擎)。将代码重写为标准易读的语法会导致性能损失。


非常整洁,尽管我很难相信编写未经缩小的代码实际上有助于除了第一次解析之外的任何事情,或者如果人们将缩小其生产代码,则总体上有所帮助。这里大多数函数不需要剥离哈希部分,因为它们以location.search开头,其中不包含它。我也不清楚您所说的“位运算符”是什么意思-您在几个地方使用了空或未定义为false,这是最接近的,但这里没有位操作。 - Rup
如果您在数组中使用的不仅是复选框值,请添加以下内容:if (v.charAt(0) == '[') { v = v.replace('[', '["').replace(']', '"]').replace(',', '","'); v = JSON && JSON.parse(v) || $.parseJSON(v); },然后再添加 "c[k]?typeof ..."。 - Alex
我需要一个支持对象数组的。 - brauliobo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接