【问题标题】:Convert a nested object/ associative array into a query string using JavaScript使用 JavaScript 将嵌套对象/关联数组转换为查询字符串
【发布时间】:2017-06-25 20:38:07
【问题描述】:

我想使用 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 的答案。

我该怎么做?

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 什么意思?我没有添加实现。我要求实施。我也相信我提供的 URL 编码很好。看看:freeformatter.com/url-parser-query-string-splitter.html 并粘贴 URL 自己看看。
    • 我想说的是,你将要实现的实现很可能比现有的模块更糟糕,这些模块关注时髦的边缘情况并带有适当的测试套房。
    • 哦,你的意思是使用图书馆
    • 没错! :) 查询字符串将立即解决您的问题。它来自一位知名开发人员,如果您查看source,您会发现正确处理这些事情并非易事。
    • 我既没有使用过 Alloy 也没有使用过 Titanium,但如果它们真的让使用第三方 npm 模块变得不可能/太难了,我可能会从查询字符串模块中提取相关部分,或者只是完全复制它。它只有两个依赖项:一个将 Object.assign 方法引入 Node-versions 4 及以下版本(希望您在 Titanium/Alloy 中不需要它),另一个(strict-uri-encode)基本上是one line of code .
    【解决方案2】:

    你可以这样做:

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

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

    【讨论】:

      【解决方案3】:

      使用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>

      更多信息您可以访问this answer

      祝你好运……

      【讨论】:

      • 为我节省了大量时间,甚至更多行代码..
      猜你喜欢
      • 1970-01-01
      • 2020-11-21
      • 1970-01-01
      • 2020-03-23
      • 1970-01-01
      • 2021-02-21
      • 2012-03-01
      • 1970-01-01
      相关资源
      最近更新 更多