JavaScript查询字符串


106

是否有任何JavaScript库可根据查询字符串,ASP.NET样式创建字典?

可以像这样使用的东西:

var query = window.location.querystring["query"]?

“查询字符串”是否在.NET领域之外称为其他名称?为什么不location.search分解为键/值集合

编辑:我已经编写了自己的函数,但是任何主要的JavaScript库都可以这样做吗?





1
@davidtaubmann那个年龄大一点,那就相反了。有趣的是,他们本质上都提出了相同的要求,但是由于问题的形式,一个人的荣耀变成了社区的荣耀,而其他人则变成了题外话。
安德烈·菲盖雷多

Answers:


11

37
这应该是jquery的本机
gcb 2011年

@EvanMulawski谢谢。插件似乎消失了。我添加了其他链接,可能会有帮助。
Shadow2531 2011年

CMS提供的方法更容易,更清洁。Esp。如果您尚未使用jquery。
jcoffland 2012年

1
您可以参考这个库来做到这一点-github.com/Mikhus/jsurl
Mikhus 2013年


230

您可以从location.search属性中提取键/值对,该属性具有URL中位于?之后的部分。符号,包括?符号。

function getQueryString() {
  var result = {}, queryString = location.search.slice(1),
      re = /([^&=]+)=([^&]*)/g, m;

  while (m = re.exec(queryString)) {
    result[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }

  return result;
}

// ...
var myParam = getQueryString()["myParam"];

11
这不是胜利。如果键的值中带有'='字符怎么办?例如dork.com/?equation=10=2。您可能会争辩说它应该是URL编码的,但肯定不是必须的。我犯了一次自己编写这样一个幼稚函数的错误。此功能说明了不只一种情况。
JamesBrownIsDead 2010年

6
@James,忘记提了,几个月前我修改了该函数,现在它可以正确处理您的示例了dork.com/?equation=10=2……
CMS 2010年

2
@CMS不能处理查询字符串中表示为数组的可能性,?val=foo&val=bar&val=baz 您将如何适应呢?
Russ Bradberry 2010年

2
@RussBradberry你真的不能拥有吗val=foo&val=bar&val=baz?一定是val[]=foo&val[]=bar&val[]=baz
Brian Driscoll

1
当我的值包含空格并且var以%20's 结尾时,这对我来说似乎不完整,所以我result[keyValuePair[0]] = keyValuePair[1] || '';result[keyValuePair[0]] = decodeURIComponent((keyValuePair[1]+'').replace(/\+/g, '%20')) || '';
user24601'1

22

tl; dr解决方案使用香草javascript处理一行代码

var queryDict = {}
location.search.substr(1).split("&").forEach(function(item) {
    queryDict[item.split("=")[0]] = item.split("=")[1]
})

对于querystring,?a=1&b=2&c=3&d&e它返回:

> queryDict
a: "1"
b: "2"
c: "3"
d: undefined
e: undefined

多值键编码字符

请参阅如何在JavaScript中获取查询字符串值的原始答案

"?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%26car%3Dsaab"
> queryDict
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"]

8
这不是一行,而是几行格式错误!
JonnyRaa 2014年

1
该死的,我不知道该说些什么...你救了我。这里,有一些多行解决方案:`var queryDict = {}; location.search.substr(1).split(“&”)。forEach(function(item){queryDict [item.split(“ =”)[0]] = item.split(“ =”)[1]; });`
Qwerty 2014年

2
哈哈,我喜欢它!抱歉,我曾经和一个曾经说过“我发现一个可以做x的衬里”的人一起工作,然后只向您显示3行,其中包含换行符!
JonnyRaa 2014年

@JonnyLeeds没问题,我确切地知道您的意思,但是,为什么一个人在换行符上写每个链接的命令?然后有一个作为参数给定的函数(通常是内联参数),该函数只有一个分配。内联尖叫!:D
Qwerty 2015年

1
@Qwerty,可能是因为您的“单线”应重新格式化,以便阅读时不需要水平滚动。我已经调整了。
P I

8

找到这篇文章后,当我看着自己时,我想我应该补充一点,我认为投票最多的解决方案并不是最好的。它不处理数组值(例如?a = foo&a = bar-在这种情况下,我希望得到a返回['foo','bar'])。据我所知,它还没有考虑编码值-例如十六进制字符编码,其中%20代表一个空格(例如:?a = Hello%20World)或用于表示一个空格的加号(例如:?a = Hello + World)。

Node.js提供了看起来非常完整的查询字符串解析解决方案。由于您的项目相当隔离并且获得了许可,因此很容易取出并在您自己的项目中使用。

可以在此处查看其代码: https //github.com/joyent/node/blob/master/lib/querystring.js

可以在此处查看Node的测试:https : //github.com/joyent/node/blob/master/test/simple/test-querystring.js我建议尝试使用流行的答案尝试其中的一些,以查看其效果处理他们。

我还参与了一个项目,专门添加了此功能。它是Python标准lib查询字符串解析模块的端口。我的叉子可以在这里找到:https : //github.com/d0ugal/jquery.qeeree


不仅可以从Node.js借用代码,而且它们之间也高度交织。
铝箔

5

或者,您可以使用库sugar.js

从sugarjs.com:

Object.fromQueryString(str,deep = true

将URL的查询字符串转换为对象。如果deep为假,则转换将仅接受浅参数(即,不支持[[]语法的对象或数组),因为它们不受普遍支持。

Object.fromQueryString('foo=bar&broken=wear') >{"foo":"bar","broken":"wear"}
Object.fromQueryString('foo[]=1&foo[]=2') >{"foo":[1,2]}

例:

var queryString = Object.fromQueryString(location.search);
var foo = queryString.foo;

3

如果您手头有查询字符串,请使用以下命令:

 /**
 * @param qry the querystring
 * @param name name of parameter
 * @returns the parameter specified by name
 * @author eduardo.medeirospereira@gmail.com
 */

function getQueryStringParameter(qry,name){
    if(typeof qry !== undefined && qry !== ""){
        var keyValueArray = qry.split("&");
        for ( var i = 0; i < keyValueArray.length; i++) {
            if(keyValueArray[i].indexOf(name)>-1){
                return keyValueArray[i].split("=")[1];
            }
        }
    }
    return "";
}

2
// How about this
function queryString(qs) {
    var queryStr = qs.substr(1).split("&"),obj={};
    for(var i=0; i < queryStr.length;i++)
        obj[queryStr[i].split("=")[0]] = queryStr[i].split("=")[1];
    return obj;
}

// Usage:
var result = queryString(location.search);

这与上面投票最高的答案中的“更新:无需使用正则表达式”代码大致相同。这个问题中也有许多类似的代码)。您decodeURIComponent至少缺少提取的字符串。
Rup 2014年

@Rup,此答案后进行了更新。
Qwerty 2014年

@Qwerty不,不是:更新时间是2013年2月,而答案是将近一年后的2014年2月。我对decodeURIComponent展台的评论不过。
Rup

@Rup是,对不起。是的
Qwerty 2014年

2

值得注意的是,John Slegers提到的库确实具有jQuery依赖关系,但是这里是香草Javascript版本。

https://github.com/EldonMcGuinness/querystring.js

我只是对他的帖子发表评论,但我没有这样做的声誉。:/

例:

下面的示例处理以下(尽管不规则)查询字符串:

?foo=bar&foo=boo&roo=bar;bee=bop;=ghost;=ghost2;&;checkbox%5B%5D=b1;checkbox%5B%5D=b2;dd=;http=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab&http=http%3A%2F%2Fw3schools2.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab 

var qs = "?foo=bar&foo=boo&roo=bar;bee=bop;=ghost;=ghost2;&;checkbox%5B%5D=b1;checkbox%5B%5D=b2;dd=;http=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab&http=http%3A%2F%2Fw3schools2.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab";
//var qs = "?=&=";
//var qs = ""

var results = querystring(qs);

(document.getElementById("results")).innerHTML =JSON.stringify(results, null, 2);
<script 
src="https://rawgit.com/EldonMcGuinness/querystring.js/master/dist/querystring.min.js"></script>
<pre id="results">RESULTS: Waiting...</pre>


实际上,我确实在回答中给出的代码中删除了jQuery依赖关系;-)
John Slegers

2

代码

Eldon McGuinness撰写的 Gist是迄今为止我所见过的最完整的JavaScript查询字符串解析器实现。

不幸的是,它是作为jQuery插件编写的。

我将其重写为Vanilla JS,并进行了一些改进:

function parseQuery(str) {
  var qso = {};
  var qs = (str || document.location.search);
  // Check for an empty querystring
  if (qs == "") {
    return qso;
  }
  // Normalize the querystring
  qs = qs.replace(/(^\?)/, '').replace(/;/g, '&');
  while (qs.indexOf("&&") != -1) {
    qs = qs.replace(/&&/g, '&');
  }
  qs = qs.replace(/([\&]+$)/, '');
  // Break the querystring into parts
  qs = qs.split("&");
  // Build the querystring object
  for (var i = 0; i < qs.length; i++) {
    var qi = qs[i].split("=");
    qi = qi.map(function(n) {
      return decodeURIComponent(n)
    });
    if (typeof qi[1] === "undefined") {
      qi[1] = null;
    }
    if (typeof qso[qi[0]] !== "undefined") {

      // If a key already exists then make this an object
      if (typeof (qso[qi[0]]) == "string") {
        var temp = qso[qi[0]];
        if (qi[1] == "") {
          qi[1] = null;
        }
        qso[qi[0]] = [];
        qso[qi[0]].push(temp);
        qso[qi[0]].push(qi[1]);

      } else if (typeof (qso[qi[0]]) == "object") {
        if (qi[1] == "") {
          qi[1] = null;
        }
        qso[qi[0]].push(qi[1]);
      }
    } else {
      // If no key exists just set it as a string
      if (qi[1] == "") {
        qi[1] = null;
      }
      qso[qi[0]] = qi[1];
    }
  }
  return qso;
}

如何使用它

var results = parseQuery("?foo=bar&foo=boo&roo=bar;bee=bop;=ghost;=ghost2;&;checkbox%5B%5D=b1;checkbox%5B%5D=b2;dd=;http=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab&http=http%3A%2F%2Fw3schools2.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab");

输出量

{
  "foo": ["bar", "boo" ],
  "roo": "bar",
  "bee": "bop",
  "": ["ghost", "ghost2"],
  "checkbox[]": ["b1", "b2"],
  "dd": null,
  "http": [
    "http://w3schools.com/my test.asp?name=ståle&car=saab",
    "http://w3schools2.com/my test.asp?name=ståle&car=saab"
  ]
}

另请参阅此小提琴


1

function decode(s) {
    try {
        return decodeURIComponent(s).replace(/\r\n|\r|\n/g, "\r\n");
    } catch (e) {
        return "";
    }
}
function getQueryString(win) {
    var qs = win.location.search;
    var multimap = {};
    if (qs.length > 1) {
        qs = qs.substr(1);
        qs.replace(/([^=&]+)=([^&]*)/g, function(match, hfname, hfvalue) {
            var name = decode(hfname);
            var value = decode(hfvalue);
            if (name.length > 0) {
                if (!multimap.hasOwnProperty(name)) {
                    multimap[name] = [];
                }
                multimap[name].push(value);
            }
        });
    }
    return multimap;
}
var keys = getQueryString(window);
for (var i in keys) {
    if (keys.hasOwnProperty(i)) {
        for (var z = 0; z < keys[i].length; ++z) {
            alert(i + ":" + keys[i][z]);
        }
    }
}

如果您希望hfname匹配不区分大小写,也可以.toLowerCase()名称。
Shadow2531,2009年

您还可以检查该值是否为空。如果是这样,则可以跳过添加条目的操作,以便数组仅包含非空值。
Shadow2531,2009年

1
unescape()不处理UTF-8序列,因此您可能要使用encodeURIComponent()。但是,如果您希望将+字符解码为空格,请在解码之前对字符串运行.replace(/ \ + / g,“”)。
Shadow2531,2009年

1

我喜欢保持简单,易读且小巧。

function searchToObject(search) {
    var pairs = search.substring(1).split("&"),
        obj = {}, pair;

    for (var i in pairs) {
        if (pairs[i] === "") continue;
        pair = pairs[i].split("=");
        obj[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
    }
    return obj;
}

searchToObject(location.search);

例:

searchToObject('?query=myvalue')['query']; // spits out: 'myvalue'

1

我为纯JavaScript字符串操纵针对此要求编写的函数

"http://www.google.lk/?Name=John&Age=20&Gender=Male"

function queryize(sampleurl){
    var tokens = url.split('?')[1].split('&');
    var result = {};

    for(var i=0; i<tokens.length; i++){
        result[tokens[i].split('=')[0]] = tokens[i].split('=')[1];
    }

    return result;
}

用法:

queryize(window.location.href)['Name'] //returns John
queryize(window.location.href)['Age'] //returns 20
queryize(window.location.href)['Gender'] //returns Male

整洁,但是除了删除领导的方式与您?上方的两个答案基本相同之外,还可以吗?
Rup

只是一个小改进。该方法的使用方式使用户易于使用。用户只需要知道他需要什么查询字符串值。
Pranavan Maru 2014年

1

如果您使用lodash + ES6,这是一种解决方案: _.object(window.location.search.replace(/(^\?)/, '').split('&').map(keyVal => keyVal.split('=')));


0

好的,既然每个人都忽略了我的实际问题,呵呵,我也将发布我的信息!这是我所拥有的:

location.querystring = (function() {

    // The return is a collection of key/value pairs

    var queryStringDictionary = {};

    // Gets the query string, starts with '?'

    var querystring = unescape(location.search);

    // document.location.search is empty if no query string

    if (!querystring) {
        return {};
    }

    // Remove the '?' via substring(1)

    querystring = querystring.substring(1);

    // '&' seperates key/value pairs

    var pairs = querystring.split("&");

    // Load the key/values of the return collection

    for (var i = 0; i < pairs.length; i++) {
        var keyValuePair = pairs[i].split("=");
        queryStringDictionary[keyValuePair[0]] = keyValuePair[1];
    }

    // Return the key/value pairs concatenated

    queryStringDictionary.toString = function() {

        if (queryStringDictionary.length == 0) {
            return "";
        }

        var toString = "?";

        for (var key in queryStringDictionary) {
            toString += key + "=" + queryStringDictionary[key];
        }

        return toString;
    };

    // Return the key/value dictionary

    return queryStringDictionary;
})();

和测试:

alert(window.location.querystring.toString());

for (var key in location.querystring) {
    alert(key + "=" + location.querystring[key]);
}

请注意,JavaScript不是我的母语。

无论如何,我正在寻找一个已经编写好的JavaScript库(例如jQuery,Prototype)。:)


1
我不相信您确实需要一个库来完成相当于上述三行代码的工作!尽管如此,至少您还是希望一个库能够记住keyURI和value的encodeURIComponent(),到目前为止,每个代码段都未能做到这一点。
bobince

您不需要图书馆。我想将自己的实现与库中的实现进行比较,以便可以查看是否缺少任何边缘情况。:)
核心

javascript不是您的母语,这意味着什么,即使您需要使用库也应学习它
Marwan

0

基于@CMS的答案,我有以下内容(在CoffeeScript中可以轻松转换为JavaScript):

String::to_query = ->
  [result, re, d] = [{}, /([^&=]+)=([^&]*)/g, decodeURIComponent]
  while match = re.exec(if @.match /^\?/ then @.substring(1) else @)
    result[d(match[1])] = d match[2] 
  result

您可以轻松获取所需的内容:

location.search.to_query()['my_param']

这里的胜利是一个面向对象的接口(而不是功能性的),它可以在任何字符串上完成(而不仅仅是location.search)。

如果您已经在使用JavaScript库,则该功能已经存在。例如,这里是原型的版本

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.