将查询字符串反序列化为JSON对象

21

我试图从?...&foo=bar&...中获得{foo:"bar"}的方法,但是搜索了一下只找到了jQuery.params这个反向操作的函数。请问有什么建议(使用内置的JavaScript函数、jQueryUnderscore.js都可以),或者我需要自己实现它(不算太麻烦,只是不想重复造轮子)?


2
好的,这是链接:https://dev59.com/nHNA5IYBdhLWcg3wmfAa。进行一点搜索总是有帮助的。 - ggozad
@ggozad:搜索了一下将数据转换为JSON /对象,而不仅仅是获取值。感谢提供的链接!不幸的是,这个功能在jQuery或其他地方都不是标准的。 - BreakPhreak
7个回答

15

实际上,@talsibony的上述答案并没有考虑查询字符串数组(例如test=1&test=2&test=3&check=wow&such=doge)。这是我的实现:

function queryStringToJSON(qs) {
    qs = qs || location.search.slice(1);

    var pairs = qs.split('&');
    var result = {};
    pairs.forEach(function(p) {
        var pair = p.split('=');
        var key = pair[0];
        var value = decodeURIComponent(pair[1] || '');

        if( result[key] ) {
            if( Object.prototype.toString.call( result[key] ) === '[object Array]' ) {
                result[key].push( value );
            } else {
                result[key] = [ result[key], value ];
            }
        } else {
            result[key] = value;
        }
    });

    return JSON.parse(JSON.stringify(result));
};

1
非常好的答案,谢谢。我喜欢它可以从多个选择框中创建数组。 - GTS Joe
不错的回答,但我认为在你的if语句顶部加上if (key !== "")会更好。 - mortezashojaei
1
如果值中包含 & 符号,则无法正常工作。有什么解决方案吗?test=1&test=2&2&test=3&check=wow&such=doge - Vish V
查询字符串中存在实际的“&”的情况是什么?任何URL中的“&”都不会被编码为“%26”吗? - Raphael
1
五年后,这个答案仍然很有用。谢谢。 - C J

12

我在这里发布我的函数,以防其他人查找并希望直接获得它,不需要 jQuery 原生 JS。因为我也在寻找同样的东西,最终在查看其他答案后编写了这个函数:

function queryStringToJSON(queryString) {
  if(queryString.indexOf('?') > -1){
    queryString = queryString.split('?')[1];
  }
  var pairs = queryString.split('&');
  var result = {};
  pairs.forEach(function(pair) {
    pair = pair.split('=');
    result[pair[0]] = decodeURIComponent(pair[1] || '');
  });
  return result;
}


console.log(queryStringToJSON(window.location.href)); 
console.log(queryStringToJSON('test=1&check=wow'));//Object {test: "1", check: "wow"}

1
如果值中存在“&”,则它无法正常工作。有什么解决办法吗?test=1&test=2&2&test=3&check=wow&such=doge - Vish V
1
如果有的话,我认为它需要像下面这样进行URL编码: queryStringToJSON('test6=1&test3=2%262&test1=3&check=wow&such=doge') - talsibony

9

8
在现代浏览器中,你还可以使用Object.fromEntries来更轻松地完成此操作。

function queryStringToObject(queryString) {
  const pairs = queryString.substring(1).split('&');
  // → ["foo=bar", "baz=buzz"]

  var array = pairs.map((el) => {
    const parts = el.split('=');
    return parts;
  });
  // → [["foo", "bar"], ["baz", "buzz"]]

  return Object.fromEntries(array);
  // → { "foo": "bar", "baz": "buzz" }
}

console.log(queryStringToObject('?foo=bar&baz=buzz'));


URLSearchParams 接口 可以与浏览器 URL 搜索参数进行交互。 对于URLSearchParams 浏览器的支持相当不错。

针对您的情况,可以这样使用:

console.log(
  Object.fromEntries(new URLSearchParams('foo=bar&baz=buzz'))
);


2

对于简单和扁平的查询字符串,可以使用以下方式解决问题:

const queryStringToObject = (queryString) => {
  let obj = {}
  if(queryString) {
    queryString.slice(1).split('&').map((item) => {
      const [ k, v ] = item.split('=')
      v ? obj[k] = v : null
    })
  }
  return obj
}

> queryStringToObject('?foo=bar&baz=buzz')
{ foo: 'bar', baz: 'buzz' }

它会删除查询字符串中的第一个字符,例如 data=thisisatestdata - Amirition
如果您包含问号,那么您可能需要删除对 slice 的调用,或者考虑扩展该方法以支持两种字符串类型。 - lfender6445
如果查询字符串中存在空值,则它会从对象中删除该键,而应该是将其替换为空字符串。 - Sunil Lulla

1

0

我知道这个帖子有点老了 - 但是这就是对我有效的方法 - 希望它也能帮助到其他人..

var _searchModel = yourquerystring.split("&");
for (var x = 0; x < _searchModel.length; x++) {
  //break each set into key and value pair
  var _kv = _searchModel[x].split("=");

  //console.log(_kv);

  var _fieldID = _kv[0];
  var _fieldVal = _kv[1];
}


代码片段现在按预期工作,但出现了错误“ReferenceError:yourquerystring未定义”。 - dipenparmar12

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