Convert JavaScript object into URI-encoded string

后端 未结 11 1364
庸人自扰
庸人自扰 2020-12-04 18:54

I got a JavaScript object which I would like to get x-www-form-urlencoded.

Something like $(\'#myform\').serialize() but for objects.

相关标签:
11条回答
  • 2020-12-04 19:29

    An extension to @Grallen's Answer 1 – if you need a shorter URL:

    Input:

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

    Output:

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

    Instead of:

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

    0 讨论(0)
  • 2020-12-04 19:30

    See jQuery.param(...). Converts to uri, see link for more information!

    0 讨论(0)
  • 2020-12-04 19:30

    FYI, the accepted answer doesn't include support for nested objects. Here's one way that you can accomplish this:

    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;
    }
    
    0 讨论(0)
  • 2020-12-04 19:34

    Please look closely at both answers I provide here to determine which fits you best.


    Answer 1:

    Likely what you need: Readies a JSON to be used in a URL as a single argument, for later decoding.

    jsfiddle

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

    Result:

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

    For those who just want a function to do it:

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

    Answer 2:

    Uses a JSON as a source of key value pairs for x-www-form-urlencoded output.

    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;
    }
    
    0 讨论(0)
  • 2020-12-04 19:41

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

    Try using this.

    0 讨论(0)
  • 2020-12-04 19:43

    I'm surprised that no one has mentioned URLSearchParams

    var prms = new URLSearchParams({
      firstName: "Jonas",
      lastName: "Gauffin"
    });
    console.log(prms.toString());
    // firstName=Jonas&lastName=Gauffin
    
    0 讨论(0)
提交回复
热议问题