如何在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个回答

9
function getUrlVar(key){
    var result = new RegExp(key + "=([^&]*)", "i").exec(window.location.search); 
    return result && unescape(result[1]) || ""; 
}

https://gist.github.com/1771618


8
以下代码将创建一个对象,该对象有两个方法:
  1. isKeyExist: 检查特定参数是否存在
  2. getValue: 获取特定参数的值。

 

var QSParam = new function() {
       var qsParm = {};
       var query = window.location.search.substring(1);
       var params = query.split('&');
       for (var i = 0; i < params.length; i++) {
           var pos = params[i].indexOf('=');
           if (pos > 0) {
               var key = params[i].substring(0, pos);
               var val = params[i].substring(pos + 1);
               qsParm[key] = val;
           }
       }
       this.isKeyExist = function(query){
           if(qsParm[query]){
               return true;
           }
           else{
              return false;
           }
       };
       this.getValue = function(query){
           if(qsParm[query])
           {
               return qsParm[query];
           }
           throw "URL does not contain query "+ query;
       }
};

8

试试这个:

String.prototype.getValueByKey = function(k){
    var p = new RegExp('\\b'+k+'\\b','gi');
    return this.search(p) != -1 ? decodeURIComponent(this.substr(this.search(p)+k.length+1).substr(0,this.substr(this.search(p)+k.length+1).search(/(&|;|$)/))) : "";
};

然后像这样调用它:
if(location.search != "") location.search.getValueByKey("id");

您也可以将此用于cookie

if(navigator.cookieEnabled) document.cookie.getValueByKey("username");

这仅适用于具有 key=value[&|;|$] 格式的字符串... 无法用于对象/数组。

如果您不想使用 String.prototype... 将其移至函数中,并将字符串作为参数传递。


7

以下是我的看法。第一个函数将URL字符串解码为名称/值对的对象:

url_args_decode = function (url) {
  var args_enc, el, i, nameval, ret;
  ret = {};
  // use the DOM to parse the URL via an 'a' element
  el = document.createElement("a");
  el.href = url;
  // strip off initial ? on search and split
  args_enc = el.search.substring(1).split('&');
  for (i = 0; i < args_enc.length; i++) {
    // convert + into space, split on =, and then decode 
    args_enc[i].replace(/\+/g, ' ');
    nameval = args_enc[i].split('=', 2);
    ret[decodeURIComponent(nameval[0])]=decodeURIComponent(nameval[1]);
  }
  return ret;
};

作为额外的奖励,如果您更改一些参数,您可以使用第二个函数将参数数组放回URL字符串中:

url_args_replace = function (url, args) {
  var args_enc, el, name;
  // use the DOM to parse the URL via an 'a' element
  el = document.createElement("a");
  el.href = url;
  args_enc = [];
  // encode args to go into url
  for (name in args) {
    if (args.hasOwnProperty(name)) {
      name = encodeURIComponent(name);
      args[name] = encodeURIComponent(args[name]);
      args_enc.push(name + '=' + args[name]);
    }
  }
  if (args_enc.length > 0) {
    el.search = '?' + args_enc.join('&');
  } else {
    el.search = '';
  }
  return el.href;
};

1
如果您正在使用jQuery,那么稍后的方法(url_args_replace)可以通过$.param()来使用。 - adardesign
1
为什么要使用 document.createElement("a")? - greg
2
@greg 要在浏览器引擎中创建一个元素,它将为您解析URL并提供搜索和href方法以与URL字符串交互。 - BMitch

7
我使用以下 JavaScript 代码来获取通过 URL 传递的内容:
function getUrlVars() {
            var vars = {};
            var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
                vars[key] = value;
            });
            return vars;
        }

然后将值分配给变量,您只需要指定要获取哪个参数,例如如果URL是example.com/?I=1&p=2&f=3

您可以执行以下操作以获取这些值:

var getI = getUrlVars()["I"];
var getP = getUrlVars()["p"];
var getF = getUrlVars()["f"];

那么这些值将会是:
getI = 1, getP = 2 and getF = 3

1
虽然漏掉了对键和值的decodeURIComponent,而且正则表达式上可能也不需要i标志(不过这并不重要),但还是很整洁。 - Rup
1
但是如果你有 example.com/3 (MVC 路由),该怎么办? - JoshYates1980

6

我在这里为我的需求编写了一个小型的URL库:https://github.com/Mikhus/jsurl

这是一种更常见的JavaScript URL操作方式。同时它非常轻量级(经过压缩和gzip后不到1KB),并且具有非常简单和清晰的API。它不需要任何其他库就可以工作。

关于最初的问题,这很简单:

var u = new Url; // Current document URL
// or
var u = new Url('http://user:pass@example.com:8080/some/path?foo=bar&bar=baz#anchor');

// Looking for query string parameters
alert( u.query.bar);
alert( u.query.foo);

// Modifying query string parameters
u.query.foo = 'bla';
u.query.woo = ['hi', 'hey']

alert(u.query.foo);
alert(u.query.woo);
alert(u);

很有趣。为什么要手动解码值?您还将受到可以接受的UTF-8顶部字符代码的限制,尽管我意识到在实践中您不太可能遇到这种情况。 - Rup
为什么要这样解码,请参考此处的解释:http://unixpapa.com/js/querystring.html 实际上,我从那里的顶级注释中获取了该想法的代码。 - Mikhus
同时也不支持像filters[topic][]=list这样的对象数组。 - brauliobo

6
以下函数返回一个对象版本的查询字符串。您可以简单地编写 obj.key1obj.key2 来访问参数中的 key1key2 的值。
function getQueryStringObject()
{
    var querystring = document.location.search.replace('?','').split( '&' );
    var objQueryString={};
    var key="",val="";
    if(typeof querystring == 'undefined')
    {
        return (typeof querystring);
    }
    for(i=0;i<querystring.length;i++)
    {
        key=querystring[i].split("=")[0];
        val=querystring[i].split("=")[1];
        objQueryString[key] = val;
    }
    return objQueryString;
}

使用这个函数的方法是,您可以编写:
var obj= getQueryStringObject();
alert(obj.key1);

6

这个函数将查询字符串转换为类JSON对象,同时处理没有值和多值参数:

"use strict";
function getQuerystringData(name) {
    var data = { };
    var parameters = window.location.search.substring(1).split("&");
    for (var i = 0, j = parameters.length; i < j; i++) {
        var parameter = parameters[i].split("=");
        var parameterName = decodeURIComponent(parameter[0]);
        var parameterValue = typeof parameter[1] === "undefined" ? parameter[1] : decodeURIComponent(parameter[1]);
        var dataType = typeof data[parameterName];
        if (dataType === "undefined") {
            data[parameterName] = parameterValue;
        } else if (dataType === "array") {
            data[parameterName].push(parameterValue);
        } else {
            data[parameterName] = [data[parameterName]];
            data[parameterName].push(parameterValue);
        }
    }
    return typeof name === "string" ? data[name] : data;
}

我们对parameter[1]进行undefined检查,因为如果变量是undefineddecodeURIComponent将返回字符串"undefined",这是错误的。
用法:
"use strict";
var data = getQuerystringData();
var parameterValue = getQuerystringData("parameterName");

5

我使用这个答案并添加了可选地将URL作为参数传递的支持;如果未传递,则回退到window.location.search。显然,这对于从不是当前页面的URL获取查询字符串参数非常有用:

(function($, undef) {
  $.QueryString = function(url) {
    var pairs, qs = null, index, map = {};
    if(url == undef){
      qs = window.location.search.substr(1);
    }else{
      index = url.indexOf('?');
      if(index == -1) return {};
      qs = url.substring(index+1);
    }
    pairs = qs.split('&');
    if (pairs == "") return {};
    for (var i = 0; i < pairs.length; ++i)
    {
      var p = pairs[i].split('=');
      if(p.length != 2) continue;
      map[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
    }
    return map;
  };
})(jQuery);

5
如果您使用Underscore.jslodash,一种快速而简单的方法是:
_.object(window.location.search.slice(1).split('&').map(function (val) { return val.split('='); }));

不错。与基于分割的顶级答案相比,您缺少处理+和decodeURIComponent调用,但对于简单值来说,这已经足够了。 - Rup
是的,它只是用于获取简单的字母数字令牌。在当前的项目中,这就是我需要的全部内容,所以我不想要一个笨重的函数。 - acjay
1
这是我用来制作查询参数键值对象的代码:_.chain(document.location.search.slice(1).split('&')).invoke('split', '=').object().value() - David Fregoli

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