Convert JavaScript object into URI-encoded string

JavascriptJquery

Javascript Problem Overview


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

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

The following object:

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

would get encoded to:

firstName=Jonas&lastName=Gauffin (do note that special characters should get encoded properly)

Javascript Solutions


Solution 1 - Javascript

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

Solution 2 - Javascript

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

Solution 3 - Javascript

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

Solution 4 - Javascript

Since you were asking for a serialized object, this is probably slightly off the mark. But just in case, if your intent is to use the values within that object as individual parameters, this might be the conversion you're looking for:

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

Solution 5 - Javascript

Same as above in effect, but functional style gives an elegant expression::

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

Solution 6 - Javascript

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

Solution 7 - Javascript

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}

Solution 8 - Javascript

To build on @Claymore's answer, Here is a function to encode an object and additionally omit the trailing ampersand:

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

Solution 9 - Javascript

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
}

Solution 10 - Javascript

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

Try using this.

Solution 11 - Javascript

create a function to parse the query params.

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

Solution 12 - Javascript

You need to use JSON.stringify() to serialize the JSON/JavaScript object.

It is natively available in almost all the modern browsers but you can include the below js which will add the required library incase it is not available.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjgauffinView Question on Stackoverflow
Solution 1 - JavascriptGrallenView Answer on Stackoverflow
Solution 2 - JavascripttipsterView Answer on Stackoverflow
Solution 3 - Javascriptjb10210View Answer on Stackoverflow
Solution 4 - JavascriptkmuenkelView Answer on Stackoverflow
Solution 5 - JavascriptBaseZenView Answer on Stackoverflow
Solution 6 - JavascriptCurtView Answer on Stackoverflow
Solution 7 - JavascriptandraasparView Answer on Stackoverflow
Solution 8 - Javascriptjohnny 5View Answer on Stackoverflow
Solution 9 - JavascriptUdhayaView Answer on Stackoverflow
Solution 10 - JavascriptVaibhav CView Answer on Stackoverflow
Solution 11 - JavascriptsnitzView Answer on Stackoverflow
Solution 12 - JavascriptShankarSangoliView Answer on Stackoverflow