我有一个这样的字符串:

abc=foo&def=%5Basf%5D&xyz=5

如何将其转换为这样的JavaScript对象?

{
  abc: 'foo',
  def: '[asf]',
  xyz: 5
}

当前回答

这似乎是最好的解决方案,因为它考虑了同名的多个参数。

    function paramsToJSON(str) {
        var pairs = str.split('&');
        var result = {};
        pairs.forEach(function(pair) {
            pair = pair.split('=');
            var name = pair[0]
            var value = pair[1]
            if( name.length )
                if (result[name] !== undefined) {
                    if (!result[name].push) {
                        result[name] = [result[name]];
                    }
                    result[name].push(value || '');
                } else {
                    result[name] = value || '';
                }
        });
        return( result );
    }

<a href="index.html?x=1&x=2&x=3&y=blah">something</a>
paramsToJSON("x=1&x=2&x=3&y=blah"); 

console yields => {x: Array[3], y: "blah"} where x is an array as is proper JSON

后来我决定把它转换成一个jQuery插件…

$.fn.serializeURLParams = function() {
    var result = {};

    if( !this.is("a") || this.attr("href").indexOf("?") == -1 ) 
        return( result );

    var pairs = this.attr("href").split("?")[1].split('&');
    pairs.forEach(function(pair) {
        pair = pair.split('=');
        var name = decodeURI(pair[0])
        var value = decodeURI(pair[1])
        if( name.length )
            if (result[name] !== undefined) {
                if (!result[name].push) {
                    result[name] = [result[name]];
                }
                result[name].push(value || '');
            } else {
                result[name] = value || '';
            }
    });
    return( result )
}

<a href="index.html?x=1&x=2&x=3&y=blah">something</a>
$("a").serializeURLParams(); 

console yields => {x: Array[3], y: "blah"} where x is an array as is proper JSON

现在,第一个将只接受参数,但jQuery插件将接受整个url并返回序列化的参数。

其他回答

//under ES6 
const getUrlParamAsObject = (url = window.location.href) => {
    let searchParams = url.split('?')[1];
    const result = {};
    //in case the queryString is empty
    if (searchParams!==undefined) {
        const paramParts = searchParams.split('&');
        for(let part of paramParts) {
            let paramValuePair = part.split('=');
            //exclude the case when the param has no value
            if(paramValuePair.length===2) {
                result[paramValuePair[0]] = decodeURIComponent(paramValuePair[1]);
            }
        }

    }
    return result;
}

在2021年…请认为这是过时的。

Edit

这个编辑改进并解释了基于评论的答案。

var search = location.search.substring(1);
JSON.parse('{"' + decodeURI(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}')

例子

分五个步骤解析abc=foo&def=%5Basf%5D&xyz=5:

decodeURI: abc = foo&def = xyz (asf) = 5 转义引号:相同,因为没有引号 替换&:abc=foo","def=[asf]","xyz=5 " 5 . Replace =: abc":"foo","def":"[asf]","xyz": Suround卷曲和引用:{“abc”:“foo”、“def”:“(asf)”,“xyz”:“5”}

这是合法的JSON。

改进的解决方案允许搜索字符串中有更多字符。它使用了一个恢复函数来进行URI解码:

var search = location.search.substring(1);
JSON.parse('{"' + search.replace(/&/g, '","').replace(/=/g,'":"') + '"}', function(key, value) { return key===""?value:decodeURIComponent(value) })

例子

search = "abc=foo&def=%5Basf%5D&xyz=5&foo=b%3Dar";

给了

Object {abc: "foo", def: "[asf]", xyz: "5", foo: "b=ar"}

原来的答案

一行程序:

JSON.parse('{"' + decodeURI("abc=foo&def=%5Basf%5D&xyz=5".replace(/&/g, "\",\"").replace(/=/g,"\":\"")) + '"}')

2023年一行方法

一般情况下,你想要解析查询参数到一个对象:

Object.fromEntries(new URLSearchParams(location.search));

针对您的具体情况:

Object.fromEntries(new URLSearchParams('abc=foo&def=%5Basf%5D&xyz=5'));

如果你正在使用URI.js,你可以使用:

https://medialize.github.io/URI.js/docs.html#static-parseQuery

var result = URI.parseQuery("?foo=bar&hello=world&hello=mars&bam=&yup");
result === {
  foo: "bar",
  hello: ["world", "mars"],
  bam: "",
  yup: null
};

据我所知,没有原生的解决方案。Dojo有一个内置的反序列化方法(如果您碰巧使用了该框架)。

否则,你可以自己简单地实现它:

function unserialize(str) {
  str = decodeURIComponent(str);
  var chunks = str.split('&'),
      obj = {};
  for(var c=0; c < chunks.length; c++) {
    var split = chunks[c].split('=', 2);
    obj[split[0]] = split[1];
  }
  return obj;
}

编辑:添加decodeURIComponent()