97

I need convert json object to url form like: "parameter=12&asd=1"

I done with this:

        var data = {
            'action':'actualiza_resultado',
            'postID': 1,
            'gl': 2,
            'gl2' : 3
        };

        var string_=JSON.stringify(data);

        string_=string_.replace(/{/g, "");
        string_=string_.replace(/}/g, "");
        string_=string_.replace(/:/g, "=")
        string_=string_.replace(/,/g, "&");
        string_=string_.replace(/"/g, "");

But i wonder if there any function in javascript or in JSON object to do this?

fpilee
  • 1,918
  • 2
  • 22
  • 38

14 Answers14

208

Use the URLSearchParams interface, which is built into browsers and Node.js starting with version 10, released in 2018.

const myParams = {'foo': 'hi there', 'bar': '???'};

const u = new URLSearchParams(myParams).toString();

console.log(u);

Old answer: jQuery provides param that does exactly that. If you don't use jquery, take at look at the source.

Basically, it goes like this:

url = Object.keys(data).map(function(k) {
    return encodeURIComponent(k) + '=' + encodeURIComponent(data[k])
}).join('&')
Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
georg
  • 211,518
  • 52
  • 313
  • 390
24

Using ES6 syntax:

var data = {
  'action':'actualiza_resultado',
  'postID': 1,
  'gl': 2,
  'gl2' : 3
};

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

console.log(urlParameters);
Tareq
  • 5,283
  • 2
  • 15
  • 18
  • 1
    The question was about JSON objects. However, if the JSON contains array then the solution will produce good result as well but it will need parsing on the server side. Ex: var data = { 'action':'actualiza_resultado', 'postID': 1, 'gl': 2, 'gl2' : 3, 'names': ['one','two', 'three'] }; Result: "action=actualiza_resultado&postID=1&gl=2&gl2=3&names=one,two,three" – Tareq Nov 03 '16 at 10:29
  • No need for this. There's a [built-in](https://stackoverflow.com/questions/14525178/is-there-any-native-function-to-convert-json-to-url-parameters/14525299#14525299). – Dan Dascalescu Apr 06 '22 at 18:07
  • This is missing the `encodeURIComponent` needed for URL params that is in the [accepted answer](https://stackoverflow.com/a/14525299/327074) (and most of the other answers too) – icc97 Feb 08 '23 at 19:10
14

I made an implementation that support nested objects and arrays i.e.

var data = {
    users: [
    {
      "name": "jeff",
      "tasks": [
        "Do one thing",
        "Do second thing"
      ]
    },
    {
      "name": "rick",
      "tasks": [
        "Never gonna give you up",
        "Never gonna let you down"
      ]
    }
  ]
}

Will be:

users[0][name]=jeff&users[0][tasks][0]=Do%20one%20thing&users[0][tasks][1]=Do%20second%20thing&users[1][name]=rick&users[1][tasks][0]=Never%20gonna%20give%20you%20up&users[1][tasks][1]=Never%20gonna%20let%20you%20down

So, here's the implementation:

var isObj = function(a) {
  if ((!!a) && (a.constructor === Object)) {
    return true;
  }
  return false;
};
var _st = function(z, g) {
  return "" + (g != "" ? "[" : "") + z + (g != "" ? "]" : "");
};
var fromObject = function(params, skipobjects, prefix) {
  if (skipobjects === void 0) {
    skipobjects = false;
  }
  if (prefix === void 0) {
    prefix = "";
  }
  var result = "";
  if (typeof(params) != "object") {
    return prefix + "=" + encodeURIComponent(params) + "&";
  }
  for (var param in params) {
    var c = "" + prefix + _st(param, prefix);
    if (isObj(params[param]) && !skipobjects) {
      result += fromObject(params[param], false, "" + c);
    } else if (Array.isArray(params[param]) && !skipobjects) {
      params[param].forEach(function(item, ind) {
        result += fromObject(item, false, c + "[" + ind + "]");
      });
    } else {
      result += c + "=" + encodeURIComponent(params[param]) + "&";
    }
  }
  return result;
};

var data = {
  users: [{
      "name": "jeff",
      "tasks": [
        "Do one thing",
        "Do second thing"
      ]
    },
    {
      "name": "rick",
      "tasks": [
        "Never gonna give you up",
        "Never gonna let you down"
      ]
    }
  ]
}

document.write(fromObject(data));
  • 2
    Underrated answer! +1 – Uche Ozoemena Aug 25 '20 at 22:42
  • but how to decode this encoded string? – leonardosccd Jan 19 '22 at 08:55
  • Nesting is not specced and has many edge cases. See the [query-string module](https://github.com/sindresorhus/query-string#nesting). In most cases, you'll want to use the [URLSearchParams built-in](https://stackoverflow.com/questions/14525178/is-there-any-native-function-to-convert-json-to-url-parameters/14525299#14525299). – Dan Dascalescu Apr 06 '22 at 19:37
5

You don't need to serialize this object literal.

Better approach is something like:

function getAsUriParameters(data) {
   var url = '';
   for (var prop in data) {
      url += encodeURIComponent(prop) + '=' + 
          encodeURIComponent(data[prop]) + '&';
   }
   return url.substring(0, url.length - 1)
}
getAsUriParameters(data); //"action=actualiza_resultado&postID=1&gl=2&gl2=3"
Minko Gechev
  • 25,304
  • 9
  • 61
  • 68
  • 1
    You need to call `encodeURIComponent` on `prop` and `data[prop]` to properly encode them. As written, this produces a broken URL when either key or value contains `'&'` or `'#'` or a `prop` contains `'='`. – Mike Samuel Jan 25 '13 at 15:52
  • The default `toString` will be called and probably the result will be something like `elem1%20elem2%20elem3` – Minko Gechev Jan 25 '13 at 15:56
  • @MikeSamuel: now there is a [built-in](https://stackoverflow.com/questions/14525178/is-there-any-native-function-to-convert-json-to-url-parameters/14525299#14525299). – Dan Dascalescu Apr 06 '22 at 18:08
5

Something I find nicely looking in ES6:

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

Later update (same thing, maybe a bit cleaner):

const urlfy = obj => Object
    .keys(obj)
    .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]))
    .join('&');
s3v3n
  • 8,203
  • 5
  • 42
  • 56
Cezar D.
  • 356
  • 1
  • 6
  • 12
4

Like @georg said, you can use JQuery.param for flat objects.

If you need to process complex objects, you can use JsonUri, a python package that does just that. There is JavaScript library for it as well

Disclaimer: I am the author of JSONURI

Edit: I learned much later that you can also just base64 encode your payload - most languages as support for base64 encoding/decoding

Example

x = {name: 'Petter', age: 47, places: ['Mozambique', 'Zimbabwe']}
stringRep = JSON.stringify(x)
encoded = window.btoa(stringRep)

Gives you eyJuYW1lIjoiUGV0dGVyIiwiYWdlIjo0NywicGxhY2VzIjpbIk1vemFtYmlxdWUiLCJaaW1iYWJ3ZSJdfQ==, which you can use as a uri parameter

decoded = window.atob(encoded)
originalX = JSON.parse(decoded)

Needless to say, it comes with its own caveats

Guilherme
  • 721
  • 6
  • 13
  • No need for a package nowadays. There's an isomorphic [built-in](https://stackoverflow.com/questions/14525178/is-there-any-native-function-to-convert-json-to-url-parameters/14525299#14525299). – Dan Dascalescu Apr 06 '22 at 18:09
3

But i wonder if there any function in javascript

Nothing prewritten in the core.

or json to do this?

JSON is a data format. It doesn't have functions at all.


This is a relatively trivial problem to solve though, at least for flat data structures.

Don't encode the objects as JSON, then:

function obj_to_query(obj) {
    var parts = [];
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            parts.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
        }
    }
    return "?" + parts.join('&');
}

alert(obj_to_query({
    'action': 'actualiza_resultado',
    'postID': 1,
    'gl': 2,
    'gl2': 3
}));  

There isn't a standard way to encode complex data structures (e.g. with nested objects or arrays). It wouldn't be difficult to extend this to emulate the PHP method (of having square brackets in field names) or similar though.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Perfect for what I needed: JSON to "application/x-www-form-urlencoded" converter for Angular 2 Http.post body contents. Thanks. – Chris Snowden Jan 07 '16 at 11:43
  • @Quentin will it handle if one of the parameter is an array ? – Santhosh Feb 15 '17 at 10:24
  • @SanKrish — I was explicit about that in the answer which says "at least for flat data structures" as well as the entire last paragraph. – Quentin Feb 15 '17 at 10:31
  • Now there's a [built-in](https://stackoverflow.com/questions/14525178/is-there-any-native-function-to-convert-json-to-url-parameters/14525299#14525299). – Dan Dascalescu Apr 06 '22 at 18:09
3

This one processes arrays with by changing the nameinto mutiple name[]

function getAsUriParameters (data) {
  return Object.keys(data).map(function (k) {
    if (_.isArray(data[k])) {
      var keyE = encodeURIComponent(k + '[]');
      return data[k].map(function (subData) {
        return keyE + '=' + encodeURIComponent(subData);
      }).join('&');
    } else {
      return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]);
    }
  }).join('&');
};
Perki
  • 656
  • 6
  • 5
2

The conversion from a JSON string to a URL query string can be done in a single line:

const json = '{"action":"actualiza_resultado","postID":1,"gl":2,"gl2":3}';
const queryString = new URLSearchParams(JSON.parse(json)).toString();

queryString would then be set to "action=actualiza_resultado&postID=1&gl=2&gl2=3".

Steve Chambers
  • 37,270
  • 24
  • 156
  • 208
1

Best solution for Vanilla JavaScript:

var params = Object.keys(data)
  .filter(function (key) {
    return data[key] ? true : false
  })
  .map(function (key) {
    return encodeURIComponent(key) + '=' + encodeURIComponent(data[key])
  })
  .join('&');

PS: The filter is used here to remove null or undefined parameters. It makes the url look cleaner.

abelabbesnabi
  • 1,819
  • 1
  • 16
  • 21
  • No, this isn't the best solution for vanilla JS. That would be to [use the built-in](https://stackoverflow.com/questions/14525178/is-there-any-native-function-to-convert-json-to-url-parameters/14525299#14525299), which had been around for a few years before this answer was written. – Dan Dascalescu Apr 06 '22 at 18:05
0

The custom code above only handles flat data. And JQuery is not available in react native. So here is a js solution that does work with multi-level objects and arrays in react native.

function formurlencoded(data) {
const opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

let sorted = Boolean(opts.sorted),
    skipIndex = Boolean(opts.skipIndex),
    ignorenull = Boolean(opts.ignorenull),
    encode = function encode(value) {
        return String(value).replace(/(?:[\0-\x1F"-&\+-\}\x7F-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/g, encodeURIComponent).replace(/ /g, '+').replace(/[!'()~\*]/g, function (ch) {
            return '%' + ch.charCodeAt().toString(16).slice(-2).toUpperCase();
        });
    },
    keys = function keys(obj) {
        const keyarr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Object.keys(obj);
        return sorted ? keyarr.sort() : keyarr;
    },
    filterjoin = function filterjoin(arr) {
        return arr.filter(function (e) {
            return e;
        }).join('&');
    },
    objnest = function objnest(name, obj) {
        return filterjoin(keys(obj).map(function (key) {
            return nest(name + '[' + key + ']', obj[key]);
        }));
    },
    arrnest = function arrnest(name, arr) {
        return arr.length ? filterjoin(arr.map(function (elem, index) {
            return skipIndex ? nest(name + '[]', elem) : nest(name + '[' + index + ']', elem);
        })) : encode(name + '[]');
    },
    nest = function nest(name, value) {
        const type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : typeof value === 'undefined' ? 'undefined' : typeof(value);
        let f = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;

        if (value === f) f = ignorenull ? f : encode(name) + '=' + f; else if (/string|number|boolean/.test(type)) f = encode(name) + '=' + encode(value); else if (Array.isArray(value)) f = arrnest(name, value); else if (type === 'object') f = objnest(name, value);

        return f;
    };

return data && filterjoin(keys(data).map(function (key) {
    return nest(key, data[key]);
}));

}

josh123a123
  • 2,070
  • 1
  • 13
  • 21
  • Beware that nesting is not specced and has many edge cases. See the [query-string module](https://github.com/sindresorhus/query-string#nesting). In most cases, you'll want to use the [URLSearchParams built-in](https://stackoverflow.com/questions/14525178/is-there-any-native-function-to-convert-json-to-url-parameters/14525299#14525299). – Dan Dascalescu Apr 06 '22 at 19:40
-1

Based on georg's answer, but also adding ? before the string and using ES6:

  const query = !params ? '': Object.keys(params).map((k, idx) => {
    let prefix = '';
    if (idx === 0) {
      prefix = '?';
    }
    return prefix + encodeURIComponent(k) + '=' + encodeURIComponent(params[k]);
  }).join('&');
dude
  • 5,678
  • 11
  • 54
  • 81
  • No need for this, as there's a [built-in](https://stackoverflow.com/questions/14525178/is-there-any-native-function-to-convert-json-to-url-parameters/14525299#14525299). – Dan Dascalescu Apr 06 '22 at 18:06
-1

Make a utility if you have nodejs

const querystring = require('querystring')

export function makeQueryString(params): string {
  return querystring.stringify(params)
}

import example

import { makeQueryString } from '~/utils'

example of use

  makeQueryString({
    ...query,
    page
  })

Read the latest documentation here.

Pavel Levin
  • 646
  • 8
  • 7
  • There's no need for this. There's a [built-in](https://stackoverflow.com/questions/14525178/is-there-any-native-function-to-convert-json-to-url-parameters/14525299#14525299) and the `querystring` module has been deprecated in its favor. – Dan Dascalescu Apr 06 '22 at 19:42
-1

As most of the answers only convert flat objects to query parameters, I would like to share mine.

This function can handle flat objects, as well as nested arrays/objects while only using plain JS.

        function incapsulateInBrackets(key)
        {
            return '[' + key + ']';
        }

        function encode(object, isSubEncode=false, prefix = '')
        {
            let parts = Object.keys(object).map( (key) => {

                let encodedParts = [];

                if(Array.isArray(object[key]))
                {
                    object[key].map(function(innerKey, index){

                        encodedParts.push( encode(object[key][index], true, prefix + key + incapsulateInBrackets(index)));

                    });
                }
                else if(object[key] instanceof Object)
                {
                    Object.keys(object[key]).map( (innerKey) => {

                        if(Array.isArray(object[key][innerKey]))
                        {
                            encodedParts.push( encode(object[key][index], true, prefix + incapsulateInBrackets(key) + incapsulateInBrackets(innerKey)) );
                        }
                        else
                        {
                            encodedParts.push( prefix + incapsulateInBrackets(key) + incapsulateInBrackets(innerKey) + '=' +  object[key][innerKey] );
                        }

                    });
                }
                else
                {
                    if(isSubEncode)
                    {
                        encodedParts.push( prefix + incapsulateInBrackets(key) + '=' + object[key] );
                    }
                    else
                    {
                        encodedParts.push( key + '=' + object[key] );
                    }
                }

                return encodedParts.join('&');

            });

            return parts.join('&');
        }
  • Beware that nesting is not specced and has many edge cases. See the [query-string module](https://github.com/sindresorhus/query-string#nesting). In most cases, you'll want to use the [URLSearchParams built-in](https://stackoverflow.com/questions/14525178/is-there-any-native-function-to-convert-json-to-url-parameters/14525299#14525299). – Dan Dascalescu Apr 06 '22 at 19:42
  • Unfortunately, your suggested function fully excludes Internet Explorer support. The provided answer should work on IE as well. – T ter Haar Apr 09 '22 at 20:10