【问题标题】:Convert JavaScript object into URI-encoded string将 JavaScript 对象转换为 URI 编码的字符串
【发布时间】:2012-04-12 04:04:30
【问题描述】:

我有一个 JavaScript 对象,我想获得 x-www-form-urlencoded

类似于$('#myform').serialize(),但用于对象。

以下对象:

{
    firstName: "Jonas",
    lastName: "Gauffin"
}

将被编码为:

firstName=Jonas&lastName=Gauffin(请注意特殊字符应正确编码)

【问题讨论】:

标签: javascript jquery


【解决方案1】:

您需要使用JSON.stringify() 来序列化 JSON/JavaScript 对象。

它在几乎所有现代浏览器中都原生可用,但您可以包含以下 js,以添加所需的库以防它不可用。

http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js

【讨论】:

    【解决方案2】:

    jQuery.param(...)。转换为 uri,查看链接了解更多信息!

    【讨论】:

      【解决方案3】:

      请仔细查看我在此处提供的两个答案,以确定最适合您的答案。


      答案 1:

      您可能需要:准备一个 JSON 以在 URL 中作为单个参数使用,以供以后解码。

      jsfiddle

      encodeURIComponent(JSON.stringify({"test1":"val1","test2":"val2"}))+"<div>");
      

      结果:

      %7B%22test%22%3A%22val1%22%2C%22test2%22%3A%22val2%22%7D
      

      对于那些只想要一个功能的人:

      function jsonToURI(json){ return encodeURIComponent(JSON.stringify(json)); }
      
      function uriToJSON(urijson){ return JSON.parse(decodeURIComponent(urijson)); }
      

      答案 2:

      使用 JSON 作为 x-www-form-urlencoded 输出的键值对源。

      jsfiddle

      // This should probably only be used if all JSON elements are strings
      function xwwwfurlenc(srcjson){
          if(typeof srcjson !== "object")
            if(typeof console !== "undefined"){
              console.log("\"srcjson\" is not a JSON object");
              return null;
            }
          u = encodeURIComponent;
          var urljson = "";
          var keys = Object.keys(srcjson);
          for(var i=0; i <keys.length; i++){
              urljson += u(keys[i]) + "=" + u(srcjson[keys[i]]);
              if(i < (keys.length-1))urljson+="&";
          }
          return urljson;
      }
      
      // Will only decode as strings
      // Without embedding extra information, there is no clean way to
      // know what type of variable it was.
      function dexwwwfurlenc(urljson){
          var dstjson = {};
          var ret;
          var reg = /(?:^|&)(\w+)=(\w+)/g;
          while((ret = reg.exec(urljson)) !== null){
              dstjson[ret[1]] = ret[2];
          }
          return dstjson;
      }
      

      【讨论】:

      • 这应该是标准答案。不知道为什么没有人赞成这个。
      • @monarch:因为它没有被编码为 x-www-form-urlencoded(键值对)。
      • 已更新以包含原始请求编码的答案。
      【解决方案4】:

      由于您要求的是序列化对象,因此这可能有点离题。但以防万一,如果您打算将该对象中的值用作单独的参数,这可能是您正在寻找的转换:

      var params = {
          "param1": "arg1",
          "param2": "arg2"
      };
      var query = "";
      for (key in params) {
          query += encodeURIComponent(key)+"="+encodeURIComponent(params[key])+"&";
      }
      xmlhttp.send(query);
      

      【讨论】:

      • 理论上很好,唯一的问题是结尾总会有一个尾随的“&”。我使用了一种非常相似的方法,但是我设置了数组值,然后使用了join("&amp;")。效果很好。
      【解决方案5】:

      仅供参考,接受的答案不包括对嵌套对象的支持。以下是您可以完成此任务的一种方法:

      function xwwwfurlenc(srcjson, parent=""){
          if(typeof srcjson !== "object")
            if(typeof console !== "undefined"){
              console.log("\"srcjson\" is not a JSON object");
              return null;
          }
      
          let u = encodeURIComponent;
          let urljson = "";
          let keys = Object.keys(srcjson);
      
          for(let i=0; i < keys.length; i++){
            let k = parent ? parent + "[" + keys[i] + "]" : keys[i];
      
            if(typeof srcjson[keys[i]] !== "object"){
              urljson += u(k) + "=" + u(srcjson[keys[i]]);
            } else {
              urljson += xwwwfurlenc(srcjson[keys[i]], k)
            }
            if(i < (keys.length-1))urljson+="&";
          }
      
          return urljson;
      }
      

      【讨论】:

        【解决方案6】:

        @Grallen 答案 1 的扩展 - 如果您需要更短的 URL:

        输入:

        {"q":"SomethingTM","filters":[{"kind":"A","q":"foobar"},{"kind":"B","isntIt":true}],"pagenumber":1}
        

        输出:

        ('q'~'SomethingTM'_'filters'~!('kind'~'A'_'q'~'foobar')_('kind'~'B'_'isntIt'~true)*_'pagenumber'~1)
        

        代替:

        %7B%22q%22%3A%22SomethingTM%22%2C%22filters%22%3A%5B%7B%22kind%22%3A%22A%22%2C%22q%22%3A%22foobar%22%7D%2C%7B%22kind%22%3A%22B%22%2C%22isntIt%22%3Atrue%7D%5D%2C%22pagenumber%22%3A1%7D
        

        function jsonToUri(v, r, s) {
          return encodeURIComponent(
            JSON.stringify(v, r, s)
            .replace(/[()'~_!*]/g, function(c) {
              // Replace ()'~_!* with \u0000 escape sequences
              return '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4)
            })
            .replace(/\{/g, '(')    //    { -> (
            .replace(/\}/g, ')')    //    } -> )
            .replace(/"/g,  "'")    //    " -> '
            .replace(/\:/g, '~')    //    : -> ~
            .replace(/,/g,  '_')    //    , -> _
            .replace(/\[/g, '!')    //    [ -> !
            .replace(/\]/g, '*')    //    ] -> *
          )
        }
        
        function uriToJson(t, r) {
          return JSON.parse(
            decodeURIComponent(t)
            .replace(/\(/g, '{')    //    ( -> {
            .replace(/\)/g, '}')    //    ) -> }
            .replace(/'/g,  '"')    //    ' -> "
            .replace(/~/g,  ':')    //    ~ -> :
            .replace(/_/g,  ',')    //    _ -> ,
            .replace(/\!/g, '[')    //    ! -> [
            .replace(/\*/g, ']')    //    * -> ]
            , r
          )
        }
        
        
        
        //////// TESTS ////////
        
        
        
        var a = {q: 'SomethingTM', filters: [{kind: 'A', q: 'foobar'}, {kind: 'B', isntIt: true}], pagenumber: 1}
        var b = jsonToUri(a)
        var c = uriToJson(b)
        
        console.log(b)
        // ('q'~'SomethingTM'_'filters'~!('kind'~'A'_'q'~'foobar')_('kind'~'B'_'isntIt'~true)*_'pagenumber'~1)
        
        console.log(JSON.stringify(c))
        // {"q":"SomethingTM","filters":[{"kind":"A","q":"foobar"},{"kind":"B","isntIt":true}],"pagenumber":1}
        
        var a2 = {"q":"Something(TM)","filters":[{"kind":"A*","q":"foo_bar"},{"kind":"B!","isn'tIt":true}],"page~number":1}
        var b2 = jsonToUri(a2)
        var c2 = uriToJson(b2)
        
        console.log(b2)
        // ('q'~'Something%5Cu0028TM%5Cu0029'_'filters'~!('kind'~'A%5Cu002a'_'q'~'foo%5Cu005fbar')_('kind'~'B%5Cu0021'_'isn%5Cu0027tIt'~true)*_'page%5Cu007enumber'~1)
        
        console.log(JSON.stringify(c2))
        // {"q":"Something(TM)","filters":[{"kind":"A*","q":"foo_bar"},{"kind":"B!","isn'tIt":true}],"page~number":1}

        【讨论】:

          【解决方案7】:

          以@Claymore 的回答为基础,这是一个对对象进行编码并另外省略尾随 & 符号的函数:

          encodeObject(params) {
            var query = [];
            for (let key in params) {
              let val = encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
              query.push(val);
            }
            return query.join('&');
          }
          

          【讨论】:

            【解决方案8】:

            我很惊讶没有人提到URLSearchParams

            var prms = new URLSearchParams({
              firstName: "Jonas",
              lastName: "Gauffin"
            });
            console.log(prms.toString());
            // firstName=Jonas&lastName=Gauffin
            

            【讨论】:

            • 绝对应该是公认的答案。只知道它还不能在 IE 中工作。检查 CanIUse 以了解是否已更改:caniuse.com/#search=URLSearchParams
            • 让我们面对现实吧,我们仍然使用 IE 的阿姨永远不会遇到如此复杂的应用程序?
            【解决方案9】:
            function jsonToURI(jsonObj) {
                var output = '';
                var keys = Object.keys(jsonObj);
                keys.forEach(function(key) {
                    output = output + key + '=' + jsonObj[key] + '&';
                })
                return output.slice(0, -1);
            }
            
            function uriToJSON(urijson) {
                var output = {};
                urijson = decodeURIComponent(urijson);
                urijson = urijson.split('&');
                urijson.forEach(function(param) {
                    var param = param.split('=');
                    output[param[0]] = param[1];
                })
                return output
            }
            

            【讨论】:

              【解决方案10】:

              效果与上面相同,但函数式风格给出了优雅的表达::

              const to_encoded = obj => Object.keys(obj).map(k =>
                  `${encodeURIComponent(k)}=${encodeURIComponent(obj[k])}`).join('&');
              

              【讨论】:

              【解决方案11】:

              let urlParameters = Object.entries(data).map(e =&gt; e.join('=')).join('&amp;');

              试试这个。

              【讨论】:

                【解决方案12】:

                创建一个函数来解析查询参数。

                const parseQueryParams = (query) => {
                  return Object.entries(query)
                    .map(([key, value]) => key + '=' + encodeURIComponent(value))
                    .join('&')
                }

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2010-10-09
                  • 2011-10-12
                  • 2016-07-16
                  • 1970-01-01
                  • 2011-12-17
                  相关资源
                  最近更新 更多