How to convert URL parameters to a JavaScript object?

前端 未结 30 1029
时光取名叫无心
时光取名叫无心 2020-11-22 13:57

I have a string like this:

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

How can I convert it into a JavaScript object like this?

{
          


        
相关标签:
30条回答
  • 2020-11-22 14:24

    I needed to also deal with + in the query part of the URL (decodeURIComponent doesn't), so I adapted Wolfgang's code to become:

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

    In my case, I'm using jQuery to get URL-ready form parameters, then this trick to build an object out of it and I can then easily update parameters on the object and rebuild the query URL, e.g.:

    var objForm = JSON.parse('{"' + $myForm.serialize().replace(/\+/g, ' ').replace(/&/g, '","').replace(/=/g,'":"') + '"}',
                 function(key, value) { return key===""?value:decodeURIComponent(value)});
    objForm.anyParam += stringToAddToTheParam;
    var serializedForm = $.param(objForm);
    
    0 讨论(0)
  • 2020-11-22 14:25

    The proposed solutions I found so far do not cover more complex scenarios.

    I needed to convert a query string like

    https://random.url.com?Target=Offer&Method=findAll&filters%5Bhas_goals_enabled%5D%5BTRUE%5D=1&filters%5Bstatus%5D=active&fields%5B%5D=id&fields%5B%5D=name&fields%5B%5D=default_goal_name

    into an object like:

    {
        "Target": "Offer",
        "Method": "findAll",
        "fields": [
            "id",
            "name",
            "default_goal_name"
        ],
        "filters": {
            "has_goals_enabled": {
                "TRUE": "1"
            },
            "status": "active"
        }
    }
    

    OR:

    https://random.url.com?Target=Report&Method=getStats&fields%5B%5D=Offer.name&fields%5B%5D=Advertiser.company&fields%5B%5D=Stat.clicks&fields%5B%5D=Stat.conversions&fields%5B%5D=Stat.cpa&fields%5B%5D=Stat.payout&fields%5B%5D=Stat.date&fields%5B%5D=Stat.offer_id&fields%5B%5D=Affiliate.company&groups%5B%5D=Stat.offer_id&groups%5B%5D=Stat.date&filters%5BStat.affiliate_id%5D%5Bconditional%5D=EQUAL_TO&filters%5BStat.affiliate_id%5D%5Bvalues%5D=1831&limit=9999

    INTO:

    {
        "Target": "Report",
        "Method": "getStats",
        "fields": [
            "Offer.name",
            "Advertiser.company",
            "Stat.clicks",
            "Stat.conversions",
            "Stat.cpa",
            "Stat.payout",
            "Stat.date",
            "Stat.offer_id",
            "Affiliate.company"
        ],
        "groups": [
            "Stat.offer_id",
            "Stat.date"
        ],
        "limit": "9999",
        "filters": {
            "Stat.affiliate_id": {
                "conditional": "EQUAL_TO",
                "values": "1831"
            }
        }
    }
    

    I compiled and adapted multiple solutions into one that actually works:

    CODE:

    var getParamsAsObject = function (query) {
    
        query = query.substring(query.indexOf('?') + 1);
    
        var re = /([^&=]+)=?([^&]*)/g;
        var decodeRE = /\+/g;
    
        var decode = function (str) {
            return decodeURIComponent(str.replace(decodeRE, " "));
        };
    
        var params = {}, e;
        while (e = re.exec(query)) {
            var k = decode(e[1]), v = decode(e[2]);
            if (k.substring(k.length - 2) === '[]') {
                k = k.substring(0, k.length - 2);
                (params[k] || (params[k] = [])).push(v);
            }
            else params[k] = v;
        }
    
        var assign = function (obj, keyPath, value) {
            var lastKeyIndex = keyPath.length - 1;
            for (var i = 0; i < lastKeyIndex; ++i) {
                var key = keyPath[i];
                if (!(key in obj))
                    obj[key] = {}
                obj = obj[key];
            }
            obj[keyPath[lastKeyIndex]] = value;
        }
    
        for (var prop in params) {
            var structure = prop.split('[');
            if (structure.length > 1) {
                var levels = [];
                structure.forEach(function (item, i) {
                    var key = item.replace(/[?[\]\\ ]/g, '');
                    levels.push(key);
                });
                assign(params, levels, params[prop]);
                delete(params[prop]);
            }
        }
        return params;
    };
    
    0 讨论(0)
  • 2020-11-22 14:25

    I found $.String.deparam the most complete pre built solution (can do nested objects etc.). Check out the documentation.

    0 讨论(0)
  • 2020-11-22 14:27

    This is the simple version, obviously you'll want to add some error checking:

    var obj = {};
    var pairs = queryString.split('&');
    for(i in pairs){
        var split = pairs[i].split('=');
        obj[decodeURIComponent(split[0])] = decodeURIComponent(split[1]);
    }
    
    0 讨论(0)
  • 2020-11-22 14:27

    There is no native solution that I'm aware of. Dojo has a built-in unserialization method if you use that framework by chance.

    Otherwise you can implement it yourself rather simply:

    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;
    }
    

    edit: added decodeURIComponent()

    0 讨论(0)
  • 2020-11-22 14:29

    Using ES6, URL API and URLSearchParams API.

    function objectifyQueryString(url) {
      let _url = new URL(url);
      let _params = new URLSearchParams(_url.search);
      let query = Array.from(_params.keys()).reduce((sum, value)=>{
        return Object.assign({[value]: _params.get(value)}, sum);
      }, {});
      return query;
    }
    
    0 讨论(0)
提交回复
热议问题