Pregunta

Sólo me preguntaba si hay algo integrado en Javascript que puede tomar una Forma y devolver los parámetros de la consulta, por ejemplo:"var1=valor&var2=valor2&arr[]=foo&arr[]=bar..."

Me he estado preguntando esto por años.

¿Fue útil?

Solución

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.

Otros consejos

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 línea .map... 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);

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

Ahora hay API para esto, específicamente la URLSearchParams API . Para el ejemplo dado:

const params = new URLSearchParams();
const formvals = {
   var1: "value",
   var2: "value2",
   arr: "foo",
};
for (const [key, val] of Object.entries(formvals)) {
   params.append(key, val);
}
console.log(params.toString());
// var1=value&var2=value2&arr=foo

Nota: es bonito compatible con Chrome y Firefox en estos días, pero tenga cuidado si necesita trabajar con los navegadores Microsoft y Apple, ya que la compatibilidad es parcial.

Con jQuery puede hacer esto $.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"

ES2017 (ES8)

Uso de Object.entries() , que devuelve una matriz de pares de objetos [key, value]. Por ejemplo, para {a: 1, b: 2} devolvería [['a', 1], ['b', 2]]. No es compatible (y no lo será) solo con IE.

Código:

const buildURLQuery = obj =>
      Object.entries(obj)
            .map(pair => pair.map(encodeURIComponent).join('='))
            .join('&');

Ejemplo:

buildURLQuery({name: 'John', gender: 'male'});

Resultado:

"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 utilicé), es excesivo. A menos que tenga cuidado, puede encontrar que hace demasiado & Quot; magic & Quot; (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.

Entonces, 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 necesitas un formulario para hacer esto con Prototype. Simplemente use 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'

No estoy del todo seguro, recuerdo haber visto que jQuery lo hizo hasta cierto punto, pero no maneja 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 < a href > Etiquetas 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 usar 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.

Usted puede hacer eso hoy en día con FormData y URLSearchParams sin la necesidad de recorrer nada.

const formData = new FormData(form);
const searchParams = new URLSearchParams(formData);
const queryString = searchParams.toString();

Los navegadores más antiguos se necesita un polyfill, aunque.

Estas respuestas son muy útiles, pero quiero añadir otra respuesta, que puede ayudarle a construir la URL completa.Esto puede ayudarle a concat 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);

Usted puede descargar a través de mecanismo nacional de prevención https://www.npmjs.com/package/build-url

Demo:

;(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);

Es probablemente 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 techhouse explicó.
También encontré una URI.js que crea las URL fácilmente para usted. Hay varios ejemplos que lo ayudarán: Documentación URI.js .
Aquí está 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>

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top