Flatten a javascript object to pass as querystring

前端 未结 12 1794
半阙折子戏
半阙折子戏 2020-12-04 23:24

I have a javascript object that I need to flatten into a string so that I can pass as querystring, how would I do that? i.e:

{ cost: 12345, insertBy: \'testUse

相关标签:
12条回答
  • 2020-12-04 23:48

    This is an old question, but at the top of Google searches, so I'm adding this for completeness.

    If 1) you don't want to user jQuery, but 2) you want to covert a nested object to a query string, then (building off of Tim Down and Guy's answers), use this:

    function toQueryString(obj, urlEncode) {
        //
        // Helper function that flattens an object, retaining key structer as a path array:
        //
        // Input: { prop1: 'x', prop2: { y: 1, z: 2 } }
        // Example output: [
        //     { path: [ 'prop1' ],      val: 'x' },
        //     { path: [ 'prop2', 'y' ], val: '1' },
        //     { path: [ 'prop2', 'z' ], val: '2' }
        // ]
        //
        function flattenObj(x, path) {
            var result = [];
    
            path = path || [];
            Object.keys(x).forEach(function (key) {
                if (!x.hasOwnProperty(key)) return;
    
                var newPath = path.slice();
                newPath.push(key);
    
                var vals = [];
                if (typeof x[key] == 'object') {
                    vals = flattenObj(x[key], newPath);
                } else {
                    vals.push({ path: newPath, val: x[key] });
                }
                vals.forEach(function (obj) {
                    return result.push(obj);
                });
            });
    
            return result;
        } // flattenObj
    
        // start with  flattening `obj`
        var parts = flattenObj(obj); // [ { path: [ ...parts ], val: ... }, ... ]
    
        // convert to array notation:
        parts = parts.map(function (varInfo) {
            if (varInfo.path.length == 1) varInfo.path = varInfo.path[0];else {
                var first = varInfo.path[0];
                var rest = varInfo.path.slice(1);
                varInfo.path = first + '[' + rest.join('][') + ']';
            }
            return varInfo;
        }); // parts.map
    
        // join the parts to a query-string url-component
        var queryString = parts.map(function (varInfo) {
            return varInfo.path + '=' + varInfo.val;
        }).join('&');
        if (urlEncode) return encodeURIComponent(queryString);else return queryString;
    }
    

    Use like:

    console.log(toQueryString({
        prop1: 'x',
        prop2: {
            y: 1,
            z: 2
        }
    }, false));
    

    Which outputs:

    prop1=x&prop2[y]=1&prop2[z]=2
    
    0 讨论(0)
  • 2020-12-04 23:50

    General JavaScript:

    function toParam(obj) {
      var str = "";
      var seperator = "";
      for (key in obj) {
        str += seperator;
        str += enncodeURIComponent(key) + "=" + encodeURIComponent(obj[key]);
        seperator = "&";
      }
      return str;
    }
    
    
    toParam({ cost: 12345, insertBy: 'testUser' })
    "cost=12345&insertBy=testUser"
    
    0 讨论(0)
  • 2020-12-04 23:58

    Try the $.param() method:

    var result = $.param({ cost: 12345, insertBy: 'testUser' });
    
    0 讨论(0)
  • 2020-12-05 00:00

    My ES6 version (pure Javascript, no jQuery):

    function toQueryString(paramsObject) {
      return Object
        .keys(paramsObject)
        .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(paramsObject[key])}`)
        .join('&')
      ;
    }
    
    0 讨论(0)
  • 2020-12-05 00:00
    var myObj = { cost: 12345, insertBy: 'testUser' },
        param = '',
        url   = 'http://mysite.com/mypage.php';    
    
    for (var p in myObj) {
      if (myObj.hasOwnProperty(p)) {
        param += encodeURIComponent(p) + "=" + encodeURIComponent(myObj[p]) + "&";
      }
    }
    
    window.location.href = url + "?" + param;
    
    0 讨论(0)
  • 2020-12-05 00:00

    ES6 version of Jrop's answer (also parses nested params)

    const toQueryString = (obj, urlEncode = false) => {
      if (!obj) return null;
      const flattenObj = (x, path = []) => {
        const result = [];
        Object.keys(x).forEach((key) => {
          if (!Object.prototype.hasOwnProperty.call(x, key)) return;
          const newPath = path.slice();
          newPath.push(key);
          let vals = [];
          if (typeof x[key] === 'object') {
            vals = flattenObj(x[key], newPath);
          } else {
            vals.push({ path: newPath, val: x[key] });
          }
          vals.forEach((v) => {
            return result.push(v);
          });
        });
        return result;
      };
    
      let parts = flattenObj(obj);
      parts = parts.map((varInfo) => {
        if (varInfo.path.length === 1) {
          varInfo.path = varInfo.path[0]; // eslint-disable-line no-param-reassign
        } else {
          const first = varInfo.path[0];
          const rest = varInfo.path.slice(1);
          varInfo.path = `${first}[${rest.join('][')}]`; // eslint-disable-line no-param-reassign
        }
        return varInfo;
      });
    
      const queryString = parts.map((varInfo) => {
        return `${varInfo.path}=${varInfo.val}`;
      }).join('&');
      if (urlEncode) {
        return encodeURIComponent(queryString);
      }
      return queryString;
    };
    
    0 讨论(0)
提交回复
热议问题