【问题标题】:JavaScript query string [closed]JavaScript 查询字符串 [关闭]
【发布时间】:2010-10-13 10:23:49
【问题描述】:

是否有任何 JavaScript 库可以从查询字符串中生成字典,ASP.NET 样式?

可以这样使用的东西:

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

“查询字符串” 是否被称为 .NET 领域之外的其他名称?为什么location.search 没有分解成一个键/值集合

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

【问题讨论】:

标签: javascript query-string


【解决方案1】:

代码

This Gist by Eldon McGuinness 是迄今为止我见过的最完整的 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"
  ]
}

另见this Fiddle

【讨论】:

    【解决方案2】:

    【讨论】:

    • 这应该是 jquery 原生的
    • @EvanMulawski 谢谢。插件似乎消失了。我添加了一个不同的链接,这可能会有所帮助。
    • CMS 提供的方法更简单更干净。特别是。如果您还没有使用 jquery。
    • 你可以参考这个库来做到这一点 - github.com/Mikhus/jsurl
    • 正确链接如下:plugins.jquery.com/query-object
    【解决方案3】:

    值得注意的是,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 依赖项;-)
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      tl;dr 使用 vanilla javascript 在单行(ish)代码上的解决方案

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

      对于查询字符串?a=1&amp;b=2&amp;c=3&amp;d&amp;e它返回:

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

      多值键编码字符

      How can I get query string values in 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"]
      

      【讨论】:

      • 这不是一行 - 它是几行格式错误!
      • 该死的,我不知道该说什么……你明白了。在这里,有一些多行的解决方案:` var queryDict = {}; location.search.substr(1).split("&").forEach( function(item) { queryDict[item.split("=")[0]] = item.split("=")[1]; } );`
      • 哈哈我喜欢它!抱歉,我曾经和一个曾经说“我找到了一个可以做 x 的衬里”的人一起工作,然后只给你看 3 行,去掉换行符!
      • @JonnyLeeds 没问题,我完全明白你的意思,但是,为什么要在新行上编写每个链接命令?然后有一个作为参数给出的函数(参数通常是内联的),它只有一个赋值。它尖叫着被内联! :D
      • @Qwerty,这可能是因为您的“单行”应该重新格式化,以便阅读它不需要水平滚动。我已经调整过了。
      【解决方案6】:

      我为与此类似的要求编写的函数,使用纯 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
      

      【讨论】:

      • 整洁,但除了你删除领先的? 的方式之外,它与你上面的两个答案基本相同?
      • 只是一个小小的改进。该方法的使用方式使用户很容易。用户只需要知道他需要什么查询字符串值。
      【解决方案7】:

      我喜欢保持简单、易读和小巧。

      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'
      

      【讨论】:

        【解决方案8】:

        您可以从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"];
        

        【讨论】:

        • 这不是一场胜利。如果键的值中包含“=”字符怎么办?例如。 dork.com/?equation=10=2。您可能会争辩说它应该是 URL 编码的,但它肯定不是必须的。我曾经犯过这样的错误,我自己写了一个这样的幼稚函数。这个函数有不止一种边缘情况。
        • @James,忘了说几个月前我已经修改了函数,现在它可以正确处理你的示例dork.com/?equation=10=2 ...
        • @CMS 这不能处理查询字符串中数组的可能性,该数组表示为?val=foo&amp;val=bar&amp;val=baz,您将如何适应这种情况?
        • @RussBradberry 你不可能有val=foo&amp;val=bar&amp;val=baz;它必须是val[]=foo&amp;val[]=bar&amp;val[]=baz
        • 当我的值有空格并且我的变量以 %20 结尾时,我觉得它似乎不完整,所以我用 result[keyValuePair[0]] = decodeURIComponent((keyValuePair[1]+'').replace(/\+/g, '%20')) || ''; 替换了 result[keyValuePair[0]] = keyValuePair[1] || '';
        【解决方案9】:
        // 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);
        

        【讨论】:

        • 这与上面highest-voted answer 中的“更新:无需使用正则表达式”代码或多或少相同。 this question 中也有大量类似的代码)。您至少在提取的字符串中缺少decodeURIComponent
        • @Rup,更新是在这个答案之后进行的。
        • @Qwerty 不,不是:更新是 2013 年 2 月,而这个答案是将近一年后的 2014 年 2 月。但谁在乎呢,有很多类似的代码飞来飞去。不过,我对decodeURIComponent 展台的看法是。
        • @Rup 是的,对不起。是的。
        【解决方案10】:

        或者你可以使用库sugar.js

        来自sugarjs.com:

        Object.fromQueryString (str , deep = true )

        将 URL 的查询字符串转换为对象。如果深是假的, 转换将只接受浅参数(即没有对象或数组 使用 [] 语法),因为这些不是普遍支持的。

        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;
        

        【讨论】:

          【解决方案11】:

          找到这篇文章后,当我审视自己时,我想我应该补充一点,我认为投票最多的解决方案并不是最好的。它不处理数组值(例如 ?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 标准库查询字符串解析模块的一个端口。我的叉子可以在这里找到:https://github.com/d0ugal/jquery.qeeree

          【讨论】:

          • 不只是借用 Node,js 的代码,它是高度交织的。
          【解决方案12】:

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

          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 库,则此函数已存在。例如here is Prototype's version

          【讨论】:

            【解决方案13】:

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

             /**
             * @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 "";
            }
            

            【讨论】:

              【解决方案14】:

              好吧,既然大家都忽略了我的实际问题,呵呵,我也来发一下吧!这是我所拥有的:

              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)。 :)

              【讨论】:

              • 我不相信你真的需要一个库来完成上面三行代码的工作!尽管如此,至少您希望库能够记住 decodeURIComponent() 的键和值,这是迄今为止发布的每个代码 sn-p 都未能做到的。
              • 你不需要图书馆。我想将我的实现与库中的实现进行比较,以便查看是否遗漏了任何边缘情况。 :)
              • javascript不是你的母语是什么意思,即使你需要一个库来使用也应该学习它
              【解决方案15】:
              
              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() 名称。
              • 您也可以检查该值是否为空。如果是,您可以跳过添加条目,以便数组仅包含非空值。
              • unescape() 不处理 UTF-8 序列,因此您可能需要使用 decodeURIComponent()。但是,如果您想将 + 字符解码为空格,请在解码前对字符串运行 .replace(/\+/g, " ")。
              猜你喜欢
              • 1970-01-01
              • 2013-02-15
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多