Me pregunto si hay algo incorporado en Javascript que pueda tomar un formulario y devolver los parámetros de consulta, por ejemplo: "var1=value&var2=value2&arr[]=foo&arr[]=bar..."
Me he estado preguntando esto por años.
Me pregunto si hay algo incorporado en Javascript que pueda tomar un formulario y devolver los parámetros de consulta, por ejemplo: "var1=value&var2=value2&arr[]=foo&arr[]=bar..."
Me he estado preguntando esto por años.
Respuestas:
Intenté buscar una respuesta a esta pregunta hace algún tiempo, pero terminé escribiendo mi propia función que extrae los valores del formulario.
No es perfecto pero se ajusta a mis necesidades.
function form_params( form )
{
var params = new Array()
var length = form.elements.length
for( var i = 0; i < length; i++ )
{
element = form.elements[i]
if(element.tagName == 'TEXTAREA' )
{
params[element.name] = element.value
}
else if( element.tagName == 'INPUT' )
{
if( element.type == 'text' || element.type == 'hidden' || element.type == 'password')
{
params[element.name] = element.value
}
else if( element.type == 'radio' && element.checked )
{
if( !element.value )
params[element.name] = "on"
else
params[element.name] = element.value
}
else if( element.type == 'checkbox' && element.checked )
{
if( !element.value )
params[element.name] = "on"
else
params[element.name] = element.value
}
}
}
return params;
}
form_params devuelve una asignación (clave -> valor) de los parámetros. la entrada es el elemento de formulario (elemento DOM)
No maneja campos que permiten la selección múltiple.
new Array()
para inicializar un diccionario. Pero, de nuevo, ¡el código se ve mucho más limpio que algunas de las tonterías que escribiría en estos días!
Actualización 2k20: use la solución de Josh con URLSearchParams.toString () .
Vieja respuesta:
Sin 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('&');
Para los navegadores que no admiten la sintaxis de la función de flecha que requiere ES5, cambie la .map...
línea a
.map(function(k) {return esc(k) + '=' + esc(params[k]);})
Si está utilizando jQuery, puede consultar jQuery.param()
http://api.jquery.com/jQuery.param/
Ejemplo:
var params = {
parameter1: 'value1',
parameter2: 'value2',
parameter3: 'value3'
};
var query = $.param(params);
document.write(query);
$.param($('#myform').serializeArray())
.
$('#myform').serialize()
jQuery !== JavaScript
jQuery.param()
aquí github.com/jquery/jquery/blob/master/src/serialize.js :)
someStr=value1&someObj[a]=5&someObj[b]=6&someArr[]=1&someArr[]=2
La API URLSearchParams está disponible en todos los navegadores modernos. Por ejemplo:
const params = new URLSearchParams({
var1: "value",
var2: "value2",
arr: "foo",
});
console.log(params.toString());
//Prints "var1=value&var2=value2&arr=foo"
params.append(key, value)
más tarde para agregar nuevos parámetros de búsqueda en escenarios más complicados.
x=null&y=undefined
const url = new URL("https://stackoverflow.com")
), puede configurar sus cadenas de consulta url.search = new URLSearchParams({foo: "bar"})
ourl.searchParams.append("foo", "bar")
Esto no responde directamente a su pregunta, pero aquí hay una función genérica que creará una URL que contiene parámetros de cadena de consulta. Los parámetros (nombres y valores) se escapan de forma segura para su inclusión en una 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
new Array
tiempo mientras realmente la usa como un objeto? o, O
Haciendo uso de Object.entries()
, que devuelve una matriz de [key, value]
pares de objetos . Por ejemplo, porque {a: 1, b: 2}
volvería [['a', 1], ['b', 2]]
. No es compatible (y no será) solo por IE.
const buildURLQuery = obj =>
Object.entries(obj)
.map(pair => pair.map(encodeURIComponent).join('='))
.join('&');
buildURLQuery({name: 'John', gender: 'male'});
"name=John&gender=male"
No, no creo que JavaScript estándar tenga eso incorporado, pero Prototype JS tiene esa función (seguramente la mayoría de los otros frameworks JS también lo tienen, pero no los conozco), lo llaman serializar .
Puedo recomendar Prototype JS, funciona bastante bien. El único inconveniente que realmente he notado es su tamaño (unos pocos cientos de kb) y su alcance (mucho código para ajax, dom, etc.). Por lo tanto, si solo desea un serializador de formularios, es excesivo, y estrictamente hablando, si solo desea su funcionalidad Ajax (que es principalmente para lo que lo usé), es excesivo. A menos que tenga cuidado, puede encontrar que hace demasiado "magia" (como extender cada elemento dom que toca con las funciones de Prototype JS solo para encontrar elementos), lo que lo hace lento en casos extremos.
querystring puede ayudar.
Así que puedes
const querystring = require('querystring')
url += '?' + querystring.stringify(parameters)
Si no desea utilizar una biblioteca, esto debería cubrir la mayoría / todos los mismos tipos de elementos de formulario.
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('&');
}
En realidad, no necesita un formulario para hacer esto con Prototype. Simplemente use la función Object.toQueryString :
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'
Puede hacer eso hoy en día con FormData
y URLSearchParams
sin la necesidad de repetir nada.
const formData = new FormData(form);
const searchParams = new URLSearchParams(formData);
const queryString = searchParams.toString();
Sin embargo, los navegadores más antiguos necesitarán un polyfill.
No estoy del todo seguro, recuerdo haber visto que jQuery lo hizo hasta cierto punto, pero no maneja los registros jerárquicos en absoluto, y mucho menos de una manera amigable con php.
Una cosa que sí sé con certeza es que al crear URL y pegar el producto en el dom, no solo use string-glue para hacerlo, o se abrirá a un práctico separador de páginas.
Por ejemplo, cierto software de publicidad integra la cadena de versión de lo que sea que ejecute su flash. Esto está bien cuando se trata de una cadena simple genérica de adobes, pero sin embargo, eso es muy ingenuo y explota en un lío vergonzoso para las personas que han instalado Gnash, ya que la cadena de versión de gnash contiene una licencia de copyright GPL completa, completa con URL y etiquetas <a href>. Al usar esto en el generador de anunciantes de pegamento de cadenas, se abre la página y aparece un HTML desequilibrado en el dom.
La moraleja de la historia:
var foo = document.createElement("elementnamehere");
foo.attribute = allUserSpecifiedDataConsideredDangerousHere;
somenode.appendChild(foo);
No:
document.write("<elementnamehere attribute=\""
+ ilovebrokenwebsites
+ "\">"
+ stringdata
+ "</elementnamehere>");
Google necesita aprender este truco. Traté de informar el problema, parece que no les importa.
Como dice Stein, puede utilizar la biblioteca prototipo de JavaScript de http://www.prototypejs.org . Incluya el JS y es muy simple, ¡ $('formName').serialize()
le devolverá lo que desea!
Para aquellos de nosotros que preferimos jQuery, usaría el complemento de formulario: http://plugins.jquery.com/project/form , que contiene un método formSerialize.
Puede ser un poco redundante, pero la forma más limpia que encontré se basa en algunas de las respuestas aquí:
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,
})
Estas respuestas son muy útiles, pero quiero agregar otra respuesta, que puede ayudarlo a construir una URL completa. Esto le puede ayudar a concat de base url
, path
, hash
y parameters
.
var url = buildUrl('http://mywebsite.com', {
path: 'about',
hash: 'contact',
queryParams: {
'var1': 'value',
'var2': 'value2',
'arr[]' : 'foo'
}
});
console.log(url);
Puede descargar a través de npm https://www.npmjs.com/package/build-url
Manifestación:
;(function () {
'use strict';
var root = this;
var previousBuildUrl = root.buildUrl;
var buildUrl = function (url, options) {
var queryString = [];
var key;
var builtUrl;
var caseChange;
// 'lowerCase' parameter default = false,
if (options && options.lowerCase) {
caseChange = !!options.lowerCase;
} else {
caseChange = false;
}
if (url === null) {
builtUrl = '';
} else if (typeof(url) === 'object') {
builtUrl = '';
options = url;
} else {
builtUrl = url;
}
if(builtUrl && builtUrl[builtUrl.length - 1] === '/') {
builtUrl = builtUrl.slice(0, -1);
}
if (options) {
if (options.path) {
var localVar = String(options.path).trim();
if (caseChange) {
localVar = localVar.toLowerCase();
}
if (localVar.indexOf('/') === 0) {
builtUrl += localVar;
} else {
builtUrl += '/' + localVar;
}
}
if (options.queryParams) {
for (key in options.queryParams) {
if (options.queryParams.hasOwnProperty(key) && options.queryParams[key] !== void 0) {
var encodedParam;
if (options.disableCSV && Array.isArray(options.queryParams[key]) && options.queryParams[key].length) {
for(var i = 0; i < options.queryParams[key].length; i++) {
encodedParam = encodeURIComponent(String(options.queryParams[key][i]).trim());
queryString.push(key + '=' + encodedParam);
}
} else {
if (caseChange) {
encodedParam = encodeURIComponent(String(options.queryParams[key]).trim().toLowerCase());
}
else {
encodedParam = encodeURIComponent(String(options.queryParams[key]).trim());
}
queryString.push(key + '=' + encodedParam);
}
}
}
builtUrl += '?' + queryString.join('&');
}
if (options.hash) {
if(caseChange)
builtUrl += '#' + String(options.hash).trim().toLowerCase();
else
builtUrl += '#' + String(options.hash).trim();
}
}
return builtUrl;
};
buildUrl.noConflict = function () {
root.buildUrl = previousBuildUrl;
return buildUrl;
};
if (typeof(exports) !== 'undefined') {
if (typeof(module) !== 'undefined' && module.exports) {
exports = module.exports = buildUrl;
}
exports.buildUrl = buildUrl;
} else {
root.buildUrl = buildUrl;
}
}).call(this);
var url = buildUrl('http://mywebsite.com', {
path: 'about',
hash: 'contact',
queryParams: {
'var1': 'value',
'var2': 'value2',
'arr[]' : 'foo'
}
});
console.log(url);
Sé que esta es una respuesta muy tardía pero funciona muy bien ...
var obj = {
a:"a",
b:"b"
}
Object.entries(obj).map(([key, val])=>`${key}=${val}`).join("&");
nota: object.entries devolverá clave, pares de valores
la salida de la línea anterior será a = a & b = b
Espero que ayude a alguien.
Feliz codificación ...
Probablemente sea demasiado tarde para responder a su pregunta.
Tenía la misma pregunta y no me gustaba seguir agregando cadenas para crear una URL. Entonces, comencé a usar $ .param como explicó Techhouse .
También encontré una biblioteca URI.js que crea las URL fácilmente para usted. Hay varios ejemplos que le ayudarán a: URI.js Documentación .
Aqui esta uno de ellos:
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"]);`
var params = { width:1680, height:1050 };
var str = jQuery.param( params );
console.log(str)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>