使用JavaScript将嵌套对象/关联数组转换为查询字符串

时间:2017-02-08 09:42:51

标签: javascript underscore.js query-string javascript-objects

我想使用JavaScript将对象转换为查询字符串。

例如,我想转换:

{
    a: 'hello',
    b: {
      b1: 'my',
      b2: 'friend'
      b3: {
          c: 90
      }
    }
}

为:

?a=hello&b%5Bb1%5D=my&b%5Bb2%5D=friend&b%5Bb3%5D%5Bc%5D=90

我在这里找到了不少答案:Flatten a javascript object to pass as querystring,但它们似乎没有处理关联数组(或对象内的对象)的问题。

我找到了一个很好的答案,JQuery通过使用jQuery.param工作得很好,但我想要使用原生JS或Underscore.js的答案。

我该怎么做?

3 个答案:

答案 0 :(得分:3)

我强烈建议不要重新发明现有的车轮。您自己的实现可能不那么灵活,而且更容易出错(例如,您是否考虑过正确编码查询字符串参数?)而是查看query-string模块。

答案 1 :(得分:1)

你可以这样做:

let obj = {
        a: 'hello',
        b: {
          b1: 'my',
          b2: 'friend',
          b3: {
              c: 90
          }
        }
    }

function getQueryString(obj, encode) {

      function getPathToObj(obj, path = []) {
        let result = [];

        for (let key in obj) {
          if (!obj.hasOwnProperty(key)) return;

          //deep copy
          let newPath = path.slice();
          newPath.push(key);

          let everyPath = [];
          if (typeof obj[key] === "object") {
            everyPath = getPathToObj(obj[key], newPath);
          } else {
            everyPath.push({
              path: newPath,
              val: obj[key]
            });
          }

          everyPath.map((item) => result.push(item))
        }

        return result;
      }

      function composeQueryString(paths) {
        let result = "";
        paths.map((item) => {
          let pathString = "";
          if (item.path.length > 1) {
            pathString = item.path.reduce((a, b, index) => {
              return a + '['+ b +']';
            })
          } else {
            pathString = item.path[0];
          }

          if (result) {
            pathString = "&" + pathString + '=' + item.val;
          } else {
            pathString = "?" + pathString + '=' + item.val;
          }

          result += pathString;
        });

        return result;
      }

      const str = composeQueryString(getPathToObj(obj));
      return encode === true ? encodeURI(str) : str;
    }
    console.log(getQueryString(obj, true));

get:?a = hello& b%5Bb1%5D = my& b%5Bb2%5D = friend& b%5Bb3%5D%5Bc%5D = 90

答案 2 :(得分:0)

借助Axios,您可以轻松实现以下目标:

const instance = axios.create({
  url: '/user',
  baseUrl: 'https://my-api-server'
});
const config = {
  params: {
    a: 'hello',
    b: {
      b1: 'my',
      b2: 'friend',
      b3: {
        c: 90
      }
    }
  }
}
const uri = instance.getUri(config)
document.write(uri)
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

有关更多信息,您可以访问www.example.com/shop

祝你好运...