Reputation: 101150
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)
Upvotes: 70
Views: 89911
Reputation: 1
create a function to parse the query params.
const parseQueryParams = (query) => {
return Object.entries(query)
.map(([key, value]) => key + '=' + encodeURIComponent(value))
.join('&')
}
Upvotes: 0
Reputation: 19
let urlParameters = Object.entries(data).map(e => e.join('=')).join('&');
Try using this.
Upvotes: 0
Reputation: 8718
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('&');
Upvotes: 4
Reputation: 5807
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
}
Upvotes: 1
Reputation: 796
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
Upvotes: 78
Reputation: 20995
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('&');
}
Upvotes: 2
Reputation: 1670
Please look closely at both answers I provide here to determine which fits you best.
Likely what you need: Readies a JSON to be used in a URL as a single argument, for later decoding.
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)); }
Uses a JSON as a source of key value pairs for x-www-form-urlencoded
output.
// 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;
}
Upvotes: 65
Reputation: 876
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}
Upvotes: 4
Reputation: 179
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;
}
Upvotes: 3
Reputation: 2789
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);
Upvotes: 22
Reputation: 1176
See jQuery.param(...)
. Converts to uri, see link for more information!
Upvotes: 22
Reputation: 69905
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
Upvotes: -5