Just wondering if there is anything built-in to Javascript that can take a Form and return the query parameters, eg: "var1=value&var2=value2&arr[]=foo&arr[]=bar..."
I've been wondering this for years.
This question is related to
javascript
string
forms
get
As Stein says, you can use the prototype javascript library from http://www.prototypejs.org.
Include the JS and it is very simple then, $('formName').serialize()
will return what you want!
You don't actually need a form to do this with Prototype. Just use Object.toQueryString function:
Object.toQueryString({ action: 'ship', order_id: 123, fees: ['f1', 'f2'], 'label': 'a demo' })
// -> 'action=ship&order_id=123&fees=f1&fees=f2&label=a%20demo'
Might be a bit redundant but the cleanest way i found which builds on some of the answers here:
const params: {
key1: 'value1',
key2: 'value2',
key3: 'value3',
}
const esc = encodeURIComponent;
const query = Object.keys(params)
.map(k => esc(k) + '=' + esc(params[k]))
.join('&');
return fetch('my-url', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: query,
})
Create an URL object and append the values to seachParameters
let baseURL = "http://www.google.com/search";
let url = new URL(baseURL);
let params = url.searchParams;
params.append("q","This is seach query");
console.log( url.toString() );
For those of us who prefer jQuery, you would use the form plugin: http://plugins.jquery.com/project/form, which contains a formSerialize method.
I'm not entirely certain myself, I recall seeing jQuery did it to an extent, but it doesn't handle hierarchical records at all, let alone in a php friendly way.
One thing I do know for certain, is when building URLs and sticking the product into the dom, don't just use string-glue to do it, or you'll be opening yourself to a handy page breaker.
For instance, certain advertising software in-lines the version string from whatever runs your flash. This is fine when its adobes generic simple string, but however, that's very naive, and blows up in an embarrasing mess for people whom have installed Gnash, as gnash'es version string happens to contain a full blown GPL copyright licences, complete with URLs and <a href> tags. Using this in your string-glue advertiser generator, results in the page blowing open and having imbalanced HTML turning up in the dom.
The moral of the story:
var foo = document.createElement("elementnamehere");
foo.attribute = allUserSpecifiedDataConsideredDangerousHere;
somenode.appendChild(foo);
Not:
document.write("<elementnamehere attribute=\""
+ ilovebrokenwebsites
+ "\">"
+ stringdata
+ "</elementnamehere>");
Google need to learn this trick. I tried to report the problem, they appear not to care.
The URLSearchParams API is available in all modern browsers. For example:
const params = new URLSearchParams({_x000D_
var1: "value",_x000D_
var2: "value2",_x000D_
arr: "foo",_x000D_
});_x000D_
console.log(params.toString());_x000D_
//Prints "var1=value&var2=value2&arr=foo"
_x000D_
Might be a bit redundant but the cleanest way i found which builds on some of the answers here:
const params: {
key1: 'value1',
key2: 'value2',
key3: 'value3',
}
const esc = encodeURIComponent;
const query = Object.keys(params)
.map(k => esc(k) + '=' + esc(params[k]))
.join('&');
return fetch('my-url', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: query,
})
As Stein says, you can use the prototype javascript library from http://www.prototypejs.org.
Include the JS and it is very simple then, $('formName').serialize()
will return what you want!
With jQuery you can do this by $.param
$.param({ action: 'ship', order_id: 123, fees: ['f1', 'f2'], 'label': 'a demo' })
// -> "action=ship&order_id=123&fees%5B%5D=f1&fees%5B%5D=f2&label=a+demo"
Is is probably too late to answer your question.
I had the same question and I didn't like to keep appending strings to create a URL. So, I started using $.param as techhouse explained.
I also found a URI.js library that creates the URLs easily for you. There are several examples that will help you: URI.js Documentation.
Here is one of them:
var uri = new URI("?hello=world");
uri.setSearch("hello", "mars"); // returns the URI instance for chaining
// uri == "?hello=mars"
uri.setSearch({ foo: "bar", goodbye : ["world", "mars"] });
// uri == "?hello=mars&foo=bar&goodbye=world&goodbye=mars"
uri.setSearch("goodbye", "sun");
// uri == "?hello=mars&foo=bar&goodbye=sun"
// CAUTION: beware of arrays, the following are not quite the same
// If you're dealing with PHP, you probably want the latter…
uri.setSearch("foo", ["bar", "baz"]);
uri.setSearch("foo[]", ["bar", "baz"]);`
These answers are very helpful, but i want to add another answer, that may help you build full URL.
This can help you concat base url
, path
, hash
and parameters
.
var url = buildUrl('http://mywebsite.com', {
path: 'about',
hash: 'contact',
queryParams: {
'var1': 'value',
'var2': 'value2',
'arr[]' : 'foo'
}
});
console.log(url);
You can download via npm https://www.npmjs.com/package/build-url
Demo:
;(function () {_x000D_
'use strict';_x000D_
_x000D_
var root = this;_x000D_
var previousBuildUrl = root.buildUrl;_x000D_
_x000D_
var buildUrl = function (url, options) {_x000D_
var queryString = [];_x000D_
var key;_x000D_
var builtUrl;_x000D_
var caseChange; _x000D_
_x000D_
// 'lowerCase' parameter default = false, _x000D_
if (options && options.lowerCase) {_x000D_
caseChange = !!options.lowerCase;_x000D_
} else {_x000D_
caseChange = false;_x000D_
}_x000D_
_x000D_
if (url === null) {_x000D_
builtUrl = '';_x000D_
} else if (typeof(url) === 'object') {_x000D_
builtUrl = '';_x000D_
options = url;_x000D_
} else {_x000D_
builtUrl = url;_x000D_
}_x000D_
_x000D_
if(builtUrl && builtUrl[builtUrl.length - 1] === '/') {_x000D_
builtUrl = builtUrl.slice(0, -1);_x000D_
} _x000D_
_x000D_
if (options) {_x000D_
if (options.path) {_x000D_
var localVar = String(options.path).trim(); _x000D_
if (caseChange) {_x000D_
localVar = localVar.toLowerCase();_x000D_
}_x000D_
if (localVar.indexOf('/') === 0) {_x000D_
builtUrl += localVar;_x000D_
} else {_x000D_
builtUrl += '/' + localVar;_x000D_
}_x000D_
}_x000D_
_x000D_
if (options.queryParams) {_x000D_
for (key in options.queryParams) {_x000D_
if (options.queryParams.hasOwnProperty(key) && options.queryParams[key] !== void 0) {_x000D_
var encodedParam;_x000D_
if (options.disableCSV && Array.isArray(options.queryParams[key]) && options.queryParams[key].length) {_x000D_
for(var i = 0; i < options.queryParams[key].length; i++) {_x000D_
encodedParam = encodeURIComponent(String(options.queryParams[key][i]).trim());_x000D_
queryString.push(key + '=' + encodedParam);_x000D_
}_x000D_
} else { _x000D_
if (caseChange) {_x000D_
encodedParam = encodeURIComponent(String(options.queryParams[key]).trim().toLowerCase());_x000D_
}_x000D_
else {_x000D_
encodedParam = encodeURIComponent(String(options.queryParams[key]).trim());_x000D_
}_x000D_
queryString.push(key + '=' + encodedParam);_x000D_
}_x000D_
}_x000D_
}_x000D_
builtUrl += '?' + queryString.join('&');_x000D_
}_x000D_
_x000D_
if (options.hash) {_x000D_
if(caseChange)_x000D_
builtUrl += '#' + String(options.hash).trim().toLowerCase();_x000D_
else_x000D_
builtUrl += '#' + String(options.hash).trim();_x000D_
}_x000D_
} _x000D_
return builtUrl;_x000D_
};_x000D_
_x000D_
buildUrl.noConflict = function () {_x000D_
root.buildUrl = previousBuildUrl;_x000D_
return buildUrl;_x000D_
};_x000D_
_x000D_
if (typeof(exports) !== 'undefined') {_x000D_
if (typeof(module) !== 'undefined' && module.exports) {_x000D_
exports = module.exports = buildUrl;_x000D_
}_x000D_
exports.buildUrl = buildUrl;_x000D_
} else {_x000D_
root.buildUrl = buildUrl;_x000D_
}_x000D_
}).call(this);_x000D_
_x000D_
_x000D_
var url = buildUrl('http://mywebsite.com', {_x000D_
path: 'about',_x000D_
hash: 'contact',_x000D_
queryParams: {_x000D_
'var1': 'value',_x000D_
'var2': 'value2',_x000D_
'arr[]' : 'foo'_x000D_
}_x000D_
});_x000D_
console.log(url);
_x000D_
If you don't want to use a library, this should cover most/all of the same form element types.
function serialize(form) {
if (!form || !form.elements) return;
var serial = [], i, j, first;
var add = function (name, value) {
serial.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));
}
var elems = form.elements;
for (i = 0; i < elems.length; i += 1, first = false) {
if (elems[i].name.length > 0) { /* don't include unnamed elements */
switch (elems[i].type) {
case 'select-one': first = true;
case 'select-multiple':
for (j = 0; j < elems[i].options.length; j += 1)
if (elems[i].options[j].selected) {
add(elems[i].name, elems[i].options[j].value);
if (first) break; /* stop searching for select-one */
}
break;
case 'checkbox':
case 'radio': if (!elems[i].checked) break; /* else continue */
default: add(elems[i].name, elems[i].value); break;
}
}
}
return serial.join('&');
}
For those of us who prefer jQuery, you would use the form plugin: http://plugins.jquery.com/project/form, which contains a formSerialize method.
You don't actually need a form to do this with Prototype. Just use Object.toQueryString function:
Object.toQueryString({ action: 'ship', order_id: 123, fees: ['f1', 'f2'], 'label': 'a demo' })
// -> 'action=ship&order_id=123&fees=f1&fees=f2&label=a%20demo'
As Stein says, you can use the prototype javascript library from http://www.prototypejs.org.
Include the JS and it is very simple then, $('formName').serialize()
will return what you want!
I'm not entirely certain myself, I recall seeing jQuery did it to an extent, but it doesn't handle hierarchical records at all, let alone in a php friendly way.
One thing I do know for certain, is when building URLs and sticking the product into the dom, don't just use string-glue to do it, or you'll be opening yourself to a handy page breaker.
For instance, certain advertising software in-lines the version string from whatever runs your flash. This is fine when its adobes generic simple string, but however, that's very naive, and blows up in an embarrasing mess for people whom have installed Gnash, as gnash'es version string happens to contain a full blown GPL copyright licences, complete with URLs and <a href> tags. Using this in your string-glue advertiser generator, results in the page blowing open and having imbalanced HTML turning up in the dom.
The moral of the story:
var foo = document.createElement("elementnamehere");
foo.attribute = allUserSpecifiedDataConsideredDangerousHere;
somenode.appendChild(foo);
Not:
document.write("<elementnamehere attribute=\""
+ ilovebrokenwebsites
+ "\">"
+ stringdata
+ "</elementnamehere>");
Google need to learn this trick. I tried to report the problem, they appear not to care.
If you don't want to use a library, this should cover most/all of the same form element types.
function serialize(form) {
if (!form || !form.elements) return;
var serial = [], i, j, first;
var add = function (name, value) {
serial.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));
}
var elems = form.elements;
for (i = 0; i < elems.length; i += 1, first = false) {
if (elems[i].name.length > 0) { /* don't include unnamed elements */
switch (elems[i].type) {
case 'select-one': first = true;
case 'select-multiple':
for (j = 0; j < elems[i].options.length; j += 1)
if (elems[i].options[j].selected) {
add(elems[i].name, elems[i].options[j].value);
if (first) break; /* stop searching for select-one */
}
break;
case 'checkbox':
case 'radio': if (!elems[i].checked) break; /* else continue */
default: add(elems[i].name, elems[i].value); break;
}
}
}
return serial.join('&');
}
This doesn't directly answer your question, but here's a generic function which will create a URL that contains query string parameters. The parameters (names and values) are safely escaped for inclusion in a URL.
function buildUrl(url, parameters){
var qs = "";
for(var key in parameters) {
var value = parameters[key];
qs += encodeURIComponent(key) + "=" + encodeURIComponent(value) + "&";
}
if (qs.length > 0){
qs = qs.substring(0, qs.length-1); //chop off last "&"
url = url + "?" + qs;
}
return url;
}
// example:
var url = "http://example.com/";
var parameters = {
name: "George Washington",
dob: "17320222"
};
console.log(buildUrl(url, parameters));
// => http://www.example.com/?name=George%20Washington&dob=17320222
Making use of Object.entries()
, which returns an array of object's [key, value]
pairs. For example, for {a: 1, b: 2}
it would return [['a', 1], ['b', 2]]
. It is not supported (and won't be) only by IE.
const buildURLQuery = obj =>
Object.entries(obj)
.map(pair => pair.map(encodeURIComponent).join('='))
.join('&');
buildURLQuery({name: 'John', gender: 'male'});
"name=John&gender=male"
You don't actually need a form to do this with Prototype. Just use Object.toQueryString function:
Object.toQueryString({ action: 'ship', order_id: 123, fees: ['f1', 'f2'], 'label': 'a demo' })
// -> 'action=ship&order_id=123&fees=f1&fees=f2&label=a%20demo'
With jQuery you can do this by $.param
$.param({ action: 'ship', order_id: 123, fees: ['f1', 'f2'], 'label': 'a demo' })
// -> "action=ship&order_id=123&fees%5B%5D=f1&fees%5B%5D=f2&label=a+demo"
For those of us who prefer jQuery, you would use the form plugin: http://plugins.jquery.com/project/form, which contains a formSerialize method.
No, I don't think standard JavaScript has that built in, but Prototype JS has that function (surely most other JS frameworks have too, but I don't know them), they call it serialize.
I can reccomend Prototype JS, it works quite okay. The only drawback I've really noticed it it's size (a few hundred kb) and scope (lots of code for ajax, dom, etc.). Thus if you only want a form serializer it's overkill, and strictly speaking if you only want it's Ajax functionality (wich is mainly what I used it for) it's overkill. Unless you're careful you may find that it does a little too much "magic" (like extending every dom element it touches with Prototype JS functions just to find elements) making it slow on extreme cases.
Create an URL object and append the values to seachParameters
let baseURL = "http://www.google.com/search";
let url = new URL(baseURL);
let params = url.searchParams;
params.append("q","This is seach query");
console.log( url.toString() );
var params = { width:1680, height:1050 };_x000D_
var str = jQuery.param( params );_x000D_
_x000D_
console.log(str)
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
_x000D_
If you don't want to use a library, this should cover most/all of the same form element types.
function serialize(form) {
if (!form || !form.elements) return;
var serial = [], i, j, first;
var add = function (name, value) {
serial.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));
}
var elems = form.elements;
for (i = 0; i < elems.length; i += 1, first = false) {
if (elems[i].name.length > 0) { /* don't include unnamed elements */
switch (elems[i].type) {
case 'select-one': first = true;
case 'select-multiple':
for (j = 0; j < elems[i].options.length; j += 1)
if (elems[i].options[j].selected) {
add(elems[i].name, elems[i].options[j].value);
if (first) break; /* stop searching for select-one */
}
break;
case 'checkbox':
case 'radio': if (!elems[i].checked) break; /* else continue */
default: add(elems[i].name, elems[i].value); break;
}
}
}
return serial.join('&');
}
I'm not entirely certain myself, I recall seeing jQuery did it to an extent, but it doesn't handle hierarchical records at all, let alone in a php friendly way.
One thing I do know for certain, is when building URLs and sticking the product into the dom, don't just use string-glue to do it, or you'll be opening yourself to a handy page breaker.
For instance, certain advertising software in-lines the version string from whatever runs your flash. This is fine when its adobes generic simple string, but however, that's very naive, and blows up in an embarrasing mess for people whom have installed Gnash, as gnash'es version string happens to contain a full blown GPL copyright licences, complete with URLs and <a href> tags. Using this in your string-glue advertiser generator, results in the page blowing open and having imbalanced HTML turning up in the dom.
The moral of the story:
var foo = document.createElement("elementnamehere");
foo.attribute = allUserSpecifiedDataConsideredDangerousHere;
somenode.appendChild(foo);
Not:
document.write("<elementnamehere attribute=\""
+ ilovebrokenwebsites
+ "\">"
+ stringdata
+ "</elementnamehere>");
Google need to learn this trick. I tried to report the problem, they appear not to care.
If you're using jQuery you might want to check out jQuery.param()
http://api.jquery.com/jQuery.param/
Example:
var params = {
parameter1: 'value1',
parameter2: 'value2',
parameter3: 'value3'
};
?var query = $.param(params);
document.write(query);
As Stein says, you can use the prototype javascript library from http://www.prototypejs.org.
Include the JS and it is very simple then, $('formName').serialize()
will return what you want!
If you don't want to use a library, this should cover most/all of the same form element types.
function serialize(form) {
if (!form || !form.elements) return;
var serial = [], i, j, first;
var add = function (name, value) {
serial.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));
}
var elems = form.elements;
for (i = 0; i < elems.length; i += 1, first = false) {
if (elems[i].name.length > 0) { /* don't include unnamed elements */
switch (elems[i].type) {
case 'select-one': first = true;
case 'select-multiple':
for (j = 0; j < elems[i].options.length; j += 1)
if (elems[i].options[j].selected) {
add(elems[i].name, elems[i].options[j].value);
if (first) break; /* stop searching for select-one */
}
break;
case 'checkbox':
case 'radio': if (!elems[i].checked) break; /* else continue */
default: add(elems[i].name, elems[i].value); break;
}
}
}
return serial.join('&');
}
The URLSearchParams API is available in all modern browsers. For example:
const params = new URLSearchParams({_x000D_
var1: "value",_x000D_
var2: "value2",_x000D_
arr: "foo",_x000D_
});_x000D_
console.log(params.toString());_x000D_
//Prints "var1=value&var2=value2&arr=foo"
_x000D_
If you're using jQuery you might want to check out jQuery.param()
http://api.jquery.com/jQuery.param/
Example:
var params = {
parameter1: 'value1',
parameter2: 'value2',
parameter3: 'value3'
};
?var query = $.param(params);
document.write(query);
No, I don't think standard JavaScript has that built in, but Prototype JS has that function (surely most other JS frameworks have too, but I don't know them), they call it serialize.
I can reccomend Prototype JS, it works quite okay. The only drawback I've really noticed it it's size (a few hundred kb) and scope (lots of code for ajax, dom, etc.). Thus if you only want a form serializer it's overkill, and strictly speaking if you only want it's Ajax functionality (wich is mainly what I used it for) it's overkill. Unless you're careful you may find that it does a little too much "magic" (like extending every dom element it touches with Prototype JS functions just to find elements) making it slow on extreme cases.
For those of us who prefer jQuery, you would use the form plugin: http://plugins.jquery.com/project/form, which contains a formSerialize method.
querystring can help.
So, you can
const querystring = require('querystring')
url += '?' + querystring.stringify(parameters)
You can do that nowadays with FormData
and URLSearchParams
without the need to loop over anything.
const formData = new FormData(form);
const searchParams = new URLSearchParams(formData);
const queryString = searchParams.toString();
Older browsers will need a polyfill, though.
This doesn't directly answer your question, but here's a generic function which will create a URL that contains query string parameters. The parameters (names and values) are safely escaped for inclusion in a URL.
function buildUrl(url, parameters){
var qs = "";
for(var key in parameters) {
var value = parameters[key];
qs += encodeURIComponent(key) + "=" + encodeURIComponent(value) + "&";
}
if (qs.length > 0){
qs = qs.substring(0, qs.length-1); //chop off last "&"
url = url + "?" + qs;
}
return url;
}
// example:
var url = "http://example.com/";
var parameters = {
name: "George Washington",
dob: "17320222"
};
console.log(buildUrl(url, parameters));
// => http://www.example.com/?name=George%20Washington&dob=17320222
I know this is very late answer but works very well...
var obj = {
a:"a",
b:"b"
}
Object.entries(obj).map(([key, val])=>`${key}=${val}`).join("&");
note: object.entries will return key,values pairs
output from above line will be a=a&b=b
Hope its helps someone.
Happy Coding...
2k20 update: use Josh's solution with URLSearchParams.toString().
Old answer:
Without jQuery
var params = {
parameter1: 'value_1',
parameter2: 'value 2',
parameter3: 'value&3'
};
var esc = encodeURIComponent;
var query = Object.keys(params)
.map(k => esc(k) + '=' + esc(params[k]))
.join('&');
For browsers that don't support arrow function syntax which requires ES5, change the .map...
line to
.map(function(k) {return esc(k) + '=' + esc(params[k]);})
No, I don't think standard JavaScript has that built in, but Prototype JS has that function (surely most other JS frameworks have too, but I don't know them), they call it serialize.
I can reccomend Prototype JS, it works quite okay. The only drawback I've really noticed it it's size (a few hundred kb) and scope (lots of code for ajax, dom, etc.). Thus if you only want a form serializer it's overkill, and strictly speaking if you only want it's Ajax functionality (wich is mainly what I used it for) it's overkill. Unless you're careful you may find that it does a little too much "magic" (like extending every dom element it touches with Prototype JS functions just to find elements) making it slow on extreme cases.
var params = { width:1680, height:1050 };_x000D_
var str = jQuery.param( params );_x000D_
_x000D_
console.log(str)
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
_x000D_
You don't actually need a form to do this with Prototype. Just use Object.toQueryString function:
Object.toQueryString({ action: 'ship', order_id: 123, fees: ['f1', 'f2'], 'label': 'a demo' })
// -> 'action=ship&order_id=123&fees=f1&fees=f2&label=a%20demo'
2k20 update: use Josh's solution with URLSearchParams.toString().
Old answer:
Without jQuery
var params = {
parameter1: 'value_1',
parameter2: 'value 2',
parameter3: 'value&3'
};
var esc = encodeURIComponent;
var query = Object.keys(params)
.map(k => esc(k) + '=' + esc(params[k]))
.join('&');
For browsers that don't support arrow function syntax which requires ES5, change the .map...
line to
.map(function(k) {return esc(k) + '=' + esc(params[k]);})
These answers are very helpful, but i want to add another answer, that may help you build full URL.
This can help you concat base url
, path
, hash
and parameters
.
var url = buildUrl('http://mywebsite.com', {
path: 'about',
hash: 'contact',
queryParams: {
'var1': 'value',
'var2': 'value2',
'arr[]' : 'foo'
}
});
console.log(url);
You can download via npm https://www.npmjs.com/package/build-url
Demo:
;(function () {_x000D_
'use strict';_x000D_
_x000D_
var root = this;_x000D_
var previousBuildUrl = root.buildUrl;_x000D_
_x000D_
var buildUrl = function (url, options) {_x000D_
var queryString = [];_x000D_
var key;_x000D_
var builtUrl;_x000D_
var caseChange; _x000D_
_x000D_
// 'lowerCase' parameter default = false, _x000D_
if (options && options.lowerCase) {_x000D_
caseChange = !!options.lowerCase;_x000D_
} else {_x000D_
caseChange = false;_x000D_
}_x000D_
_x000D_
if (url === null) {_x000D_
builtUrl = '';_x000D_
} else if (typeof(url) === 'object') {_x000D_
builtUrl = '';_x000D_
options = url;_x000D_
} else {_x000D_
builtUrl = url;_x000D_
}_x000D_
_x000D_
if(builtUrl && builtUrl[builtUrl.length - 1] === '/') {_x000D_
builtUrl = builtUrl.slice(0, -1);_x000D_
} _x000D_
_x000D_
if (options) {_x000D_
if (options.path) {_x000D_
var localVar = String(options.path).trim(); _x000D_
if (caseChange) {_x000D_
localVar = localVar.toLowerCase();_x000D_
}_x000D_
if (localVar.indexOf('/') === 0) {_x000D_
builtUrl += localVar;_x000D_
} else {_x000D_
builtUrl += '/' + localVar;_x000D_
}_x000D_
}_x000D_
_x000D_
if (options.queryParams) {_x000D_
for (key in options.queryParams) {_x000D_
if (options.queryParams.hasOwnProperty(key) && options.queryParams[key] !== void 0) {_x000D_
var encodedParam;_x000D_
if (options.disableCSV && Array.isArray(options.queryParams[key]) && options.queryParams[key].length) {_x000D_
for(var i = 0; i < options.queryParams[key].length; i++) {_x000D_
encodedParam = encodeURIComponent(String(options.queryParams[key][i]).trim());_x000D_
queryString.push(key + '=' + encodedParam);_x000D_
}_x000D_
} else { _x000D_
if (caseChange) {_x000D_
encodedParam = encodeURIComponent(String(options.queryParams[key]).trim().toLowerCase());_x000D_
}_x000D_
else {_x000D_
encodedParam = encodeURIComponent(String(options.queryParams[key]).trim());_x000D_
}_x000D_
queryString.push(key + '=' + encodedParam);_x000D_
}_x000D_
}_x000D_
}_x000D_
builtUrl += '?' + queryString.join('&');_x000D_
}_x000D_
_x000D_
if (options.hash) {_x000D_
if(caseChange)_x000D_
builtUrl += '#' + String(options.hash).trim().toLowerCase();_x000D_
else_x000D_
builtUrl += '#' + String(options.hash).trim();_x000D_
}_x000D_
} _x000D_
return builtUrl;_x000D_
};_x000D_
_x000D_
buildUrl.noConflict = function () {_x000D_
root.buildUrl = previousBuildUrl;_x000D_
return buildUrl;_x000D_
};_x000D_
_x000D_
if (typeof(exports) !== 'undefined') {_x000D_
if (typeof(module) !== 'undefined' && module.exports) {_x000D_
exports = module.exports = buildUrl;_x000D_
}_x000D_
exports.buildUrl = buildUrl;_x000D_
} else {_x000D_
root.buildUrl = buildUrl;_x000D_
}_x000D_
}).call(this);_x000D_
_x000D_
_x000D_
var url = buildUrl('http://mywebsite.com', {_x000D_
path: 'about',_x000D_
hash: 'contact',_x000D_
queryParams: {_x000D_
'var1': 'value',_x000D_
'var2': 'value2',_x000D_
'arr[]' : 'foo'_x000D_
}_x000D_
});_x000D_
console.log(url);
_x000D_
I know this is very late answer but works very well...
var obj = {
a:"a",
b:"b"
}
Object.entries(obj).map(([key, val])=>`${key}=${val}`).join("&");
note: object.entries will return key,values pairs
output from above line will be a=a&b=b
Hope its helps someone.
Happy Coding...
querystring can help.
So, you can
const querystring = require('querystring')
url += '?' + querystring.stringify(parameters)
Is is probably too late to answer your question.
I had the same question and I didn't like to keep appending strings to create a URL. So, I started using $.param as techhouse explained.
I also found a URI.js library that creates the URLs easily for you. There are several examples that will help you: URI.js Documentation.
Here is one of them:
var uri = new URI("?hello=world");
uri.setSearch("hello", "mars"); // returns the URI instance for chaining
// uri == "?hello=mars"
uri.setSearch({ foo: "bar", goodbye : ["world", "mars"] });
// uri == "?hello=mars&foo=bar&goodbye=world&goodbye=mars"
uri.setSearch("goodbye", "sun");
// uri == "?hello=mars&foo=bar&goodbye=sun"
// CAUTION: beware of arrays, the following are not quite the same
// If you're dealing with PHP, you probably want the latter…
uri.setSearch("foo", ["bar", "baz"]);
uri.setSearch("foo[]", ["bar", "baz"]);`
No, I don't think standard JavaScript has that built in, but Prototype JS has that function (surely most other JS frameworks have too, but I don't know them), they call it serialize.
I can reccomend Prototype JS, it works quite okay. The only drawback I've really noticed it it's size (a few hundred kb) and scope (lots of code for ajax, dom, etc.). Thus if you only want a form serializer it's overkill, and strictly speaking if you only want it's Ajax functionality (wich is mainly what I used it for) it's overkill. Unless you're careful you may find that it does a little too much "magic" (like extending every dom element it touches with Prototype JS functions just to find elements) making it slow on extreme cases.
Making use of Object.entries()
, which returns an array of object's [key, value]
pairs. For example, for {a: 1, b: 2}
it would return [['a', 1], ['b', 2]]
. It is not supported (and won't be) only by IE.
const buildURLQuery = obj =>
Object.entries(obj)
.map(pair => pair.map(encodeURIComponent).join('='))
.join('&');
buildURLQuery({name: 'John', gender: 'male'});
"name=John&gender=male"
I'm not entirely certain myself, I recall seeing jQuery did it to an extent, but it doesn't handle hierarchical records at all, let alone in a php friendly way.
One thing I do know for certain, is when building URLs and sticking the product into the dom, don't just use string-glue to do it, or you'll be opening yourself to a handy page breaker.
For instance, certain advertising software in-lines the version string from whatever runs your flash. This is fine when its adobes generic simple string, but however, that's very naive, and blows up in an embarrasing mess for people whom have installed Gnash, as gnash'es version string happens to contain a full blown GPL copyright licences, complete with URLs and <a href> tags. Using this in your string-glue advertiser generator, results in the page blowing open and having imbalanced HTML turning up in the dom.
The moral of the story:
var foo = document.createElement("elementnamehere");
foo.attribute = allUserSpecifiedDataConsideredDangerousHere;
somenode.appendChild(foo);
Not:
document.write("<elementnamehere attribute=\""
+ ilovebrokenwebsites
+ "\">"
+ stringdata
+ "</elementnamehere>");
Google need to learn this trick. I tried to report the problem, they appear not to care.
You can do that nowadays with FormData
and URLSearchParams
without the need to loop over anything.
const formData = new FormData(form);
const searchParams = new URLSearchParams(formData);
const queryString = searchParams.toString();
Older browsers will need a polyfill, though.
Source: Stackoverflow.com