JavaScript / jQuery 中的 $.param( ) 反函数

IT技术 javascript jquery
2021-01-12 06:38:14

给定以下形式:

<form>
    <input name="foo" value="bar">
    <input name="hello" value="hello world">
</form>

我可以使用$.param( .. )构造来序列化表单:

$.param( $('form input') )

=> foo=bar&hello=hello+world

如何使用 JavaScript 反序列化上述字符串并返回哈希值?

例如,

$.magicFunction("foo=bar&hello=hello+world")

=> {'foo' : 'bar', 'hello' : 'hello world'}

参考:jQuery.param( obj )

6个回答

您应该使用jQuery BBQdeparam函数。它经过了充分的测试和记录。

如果您不想获取整个 BBQ 插件,可以在此处将 deparam 函数提取为独立插件:github.com/chrissrogers/jquery-deparam
2021-03-15 06:38:14
不错的插件!感谢分享。
2021-03-18 06:38:14
不幸的是,github 页面多年来没有看到任何更新,当我尝试它时,它似乎与最新的 jQuery 不兼容……不过看起来像我需要的。
2021-03-20 06:38:14

这是我前段时间写的一个函数的一个稍微修改的版本,用来做类似的事情。

var QueryStringToHash = function QueryStringToHash  (query) {
  var query_string = {};
  var vars = query.split("&");
  for (var i=0;i<vars.length;i++) {
    var pair = vars[i].split("=");
    pair[0] = decodeURIComponent(pair[0]);
    pair[1] = decodeURIComponent(pair[1]);
        // If first entry with this name
    if (typeof query_string[pair[0]] === "undefined") {
      query_string[pair[0]] = pair[1];
        // If second entry with this name
    } else if (typeof query_string[pair[0]] === "string") {
      var arr = [ query_string[pair[0]], pair[1] ];
      query_string[pair[0]] = arr;
        // If third or later entry with this name
    } else {
      query_string[pair[0]].push(pair[1]);
    }
  } 
  return query_string;
};
正是我认为接受的答案“这不适用于数组”。您的解决方案工作正常。
2021-04-07 06:38:14

这个简短的函数式方法怎么样?

function parseParams(str) {
    return str.split('&').reduce(function (params, param) {
        var paramSplit = param.split('=').map(function (value) {
            return decodeURIComponent(value.replace(/\+/g, ' '));
        });
        params[paramSplit[0]] = paramSplit[1];
        return params;
    }, {});
}

例子:

parseParams("this=is&just=an&example") // Object {this: "is", just: "an", example: undefined}
这应该是公认的答案,没有外部依赖。
2021-04-01 06:38:14
对于它的作用,它当然是一个很好的解决方案。但它不处理传递的数组或对象。urlfield[][]=a&field[0][]=b&field[0][]=c被处理为Object { field[][]: "a", field[0][]: "c" }它应该在的地方resultobject.field[0] = Array [ "a", "b", "c" ]这是 PHP 预期的行为。@JackyLi 的解决方案确实解决了这个问题。
2021-04-09 06:38:14
简单、可靠和强大的解决方案。尊敬,先生。
2021-04-10 06:38:14

我的答案:

function(query){
  var setValue = function(root, path, value){
    if(path.length > 1){
      var dir = path.shift();
      if( typeof root[dir] == 'undefined' ){
        root[dir] = path[0] == '' ? [] : {};
      }

      arguments.callee(root[dir], path, value);
    }else{
      if( root instanceof Array ){
        root.push(value);
      }else{
        root[path] = value;
      }
    }
  };
  var nvp = query.split('&');
  var data = {};
  for( var i = 0 ; i < nvp.length ; i++ ){
    var pair = nvp[i].split('=');
    var name = decodeURIComponent(pair[0]);
    var value = decodeURIComponent(pair[1]);

    var path = name.match(/(^[^\[]+)(\[.*\]$)?/);
    var first = path[1];
    if(path[2]){
      //case of 'array[level1]' || 'array[level1][level2]'
      path = path[2].match(/(?=\[(.*)\]$)/)[1].split('][')
    }else{
      //case of 'name'
      path = [];
    }
    path.unshift(first);

    setValue(data, path, value);
  }
  return data;
}
这是正确答案,请忽略所有其他答案,它们无法正常工作
2021-03-21 06:38:14
这个答案是唯一一个解决我的特定用例的答案(我已经将一个带有嵌套键/值的对象传递给 jQuery 的 $.param,这在检索时正确地结合了这些值)。
2021-03-21 06:38:14
这可能需要调整。我只是注意到如果查询 === "" 这在 var first = path[1]; 处有异常,因为 nvp 中有一个项目。
2021-04-01 06:38:14
迄今为止最好的解决方案 - 它表现得非常好!但是当我使用时,JSON.stringify(geturlargs('fld[2][]=2&fld[][]=3&fld[3][]=4&fld[]=bb&fld[]=cc').fld)我得到了{"2":["2"],"3":["4"],"":"cc"}而不是[null,null,[2],[3,4],"bb","cc"]我所希望的(这是 PHP 会给我的)。
2021-04-06 06:38:14
是的!是的!是的!这正是我需要解析 JQuery 在 $.ajax 调用中发送的参数的确切参数。这将返回正确嵌套的哈希值。非常感谢,李杰!
2021-04-09 06:38:14

我正在使用 David Dorward 的答案,并意识到它的行为不像 PHP 或 Ruby on Rails 解析参数的方式:

1) 一个变量只是一个数组,如果它以 结尾[],例如?choice[]=1&choice[]=12,而不是当它是?a=1&a=2

2) 当多个参数存在同名时,后面的会替换前面的,如在 PHP 服务器上(Ruby on Rails 保留第一个,忽略后面的),例如 ?a=1&b=2&a=3

所以修改大卫的版本,我有:

function QueryStringToHash(query) {

  if (query == '') return null;

  var hash = {};

  var vars = query.split("&");

  for (var i = 0; i < vars.length; i++) {
    var pair = vars[i].split("=");
    var k = decodeURIComponent(pair[0]);
    var v = decodeURIComponent(pair[1]);

    // If it is the first entry with this name
    if (typeof hash[k] === "undefined") {

      if (k.substr(k.length-2) != '[]')  // not end with []. cannot use negative index as IE doesn't understand it
        hash[k] = v;
      else
        hash[k.substr(0, k.length-2)] = [v];

    // If subsequent entry with this name and not array
    } else if (typeof hash[k] === "string") {
      hash[k] = v;  // replace it

    // If subsequent entry with this name and is array
    } else {
      hash[k.substr(0, k.length-2)].push(v);
    }
  } 
  return hash;
};

这是相当彻底的测试。

如果这可以通过 npm 提供,那就太好了
2021-03-15 06:38:14
uri 规范是 ?a=1&a=2 应该是一个数组。Ruby on Rails 和 PHP 不遵循实际规范。
2021-03-23 06:38:14
您附加到数组的行应该是hash[k.substr(0, k.length-2)] = [v];hash[k.substr(0, k.length-2)].push(v);
2021-03-30 06:38:14