2008-11-25 14 views
96

Sólo me preguntaba si hay algo incorporado para JavaScript que puede adoptar una forma y devolver los parámetros de consulta, por ejemplo: "var1 = valor & var2 = valor2 & arr [] = foo & arr [] = bar ... "¿Cómo construir la cadena de consulta con Javascript

Me lo he estado preguntando durante años.

+1

FYI: http://phpjs.org/functions/http_build_query/ –

+1

posible duplicado de [Crear parámetros de consulta en Javascript] (http://stackoverflow.com/questions/ 111529/create-query-parameters-in-javascript) – Moes

Respuesta

6

Me trataron de buscar una respuesta a esta pregunta hace algún tiempo, pero terminó escribiendo mi propia función que extrae los valores de la forma ..

que 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 un mapeo (clave -> valor) de los parámetros. la entrada es el elemento de formulario (elemento DOM)

No maneja los campos que permiten la selección múltiple.

+0

Tengo el mismo código: D late incluyendo algún marco gigante. –

+25

¿Soy yo o no responde la pregunta en absoluto? Estaba pidiendo una cadena de consulta, no una matriz mapeada. –

+0

@JakeWilson Sí, esta respuesta solo la mitad responde la pregunta. La matriz aún necesita entrar en un formato de cadena de consulta. –

3

No estoy del todo seguro de mí mismo, recuerdo haber visto jQuery lo hizo hasta cierto punto, pero no maneja los registros jerárquicos en absoluto, y mucho menos de una manera amigable php.

Una cosa que sí sé con certeza, es al construir URL y pegar el producto en el dom, no solo use cola de cadena para hacerlo, o se abrirá a un práctico interruptor de página.

Por ejemplo, cierto software de publicidad en línea la cadena de versión de lo que ejecuta su flash. Esto está bien cuando su adobe cadena simple genérica, pero sin embargo, eso es muy ingenuo, y explota en un desastre embarazoso para las personas que han instalado Gnash, ya que la cadena de versiones de Gnash'es contiene una licencia de derechos de autor de GPL completa, completa con URLs y < a href > etiquetas. Al usar esto en su generador de publicidad de cola de hilo, los resultados se abren y el HTML desequilibrado aparece 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.

+0

Right on. Document.write es * así que * 1995, de todos modos. –

10

No, no creo JavaScript estándar que se ha incorporado, pero Prototype JS tiene esa función (seguramente más otros marcos JS tienen también, pero yo no los conocen), lo llaman serialize.

Puedo recomendar Prototype JS, funciona bastante bien. El único inconveniente que realmente noté es su tamaño (unos cientos de kb) y el alcance (muchos códigos para ajax, dom, etc.). Por lo tanto, si solo quieres un serializador de formularios, es exagerado, y estrictamente hablando, si solo quieres su funcionalidad Ajax (que es principalmente para lo que yo la utilicé) es exagerada. A menos que tenga cuidado, puede encontrar que hace demasiada "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.

+0

Solo me pregunto si hay algo incorporado. Parece que debería haber. Odio el prototipo, pero no lo estoy sosteniendo en tu contra :) –

+0

Cuando se diseñó JavaScript, Ajax aún no se había descubierto, por lo tanto, analizar un formulario solo para obtener la cadena de consulta (que se crearía al enviarlo) probablemente no hizo mucho sentido. Hoy lo hace, difícil ... Por cierto, en comparación con script.aculo.us, el prototipo es * agradable *. :) –

3

Como dice Stein, puede usar el prototipo de la biblioteca JavaScript desde http://www.prototypejs.org. Incluye el JS y es muy simple, ¡$('formName').serialize() devolverá lo que quieras!

6

Si no desea utilizar una biblioteca, debería abarcar la mayoría o 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('&'); 
} 
+0

¡Gracias! Estaba enfrentando el mismo problema que el póster original, y tu función era exactamente lo que necesitaba. – dagw

5

No necesita realmente un formulario para hacer esto con Prototype. Sólo tiene que utilizar 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' 
51

Esto no responde directamente a su pregunta, pero aquí es una función genérica que creará una dirección URL que contiene los parámetros de cadena de consulta. Los parámetros (nombres y valores) se escapan con seguridad 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 
+1

¿Hay alguna función incorporada similar a esta en uno de los populares marcos de JavaScript como jquery, mootools, etc ...? – Samuel

+0

Una solución de JavaScript nativa más robusta está en http://stackoverflow.com/a/1714899/1269037 –

+0

La implementación más extraña de la historia, ¿por qué necesita inicializar una 'nueva matriz' mientras la usa como objeto? o, O –

103

Si estás usando jQuery es posible que desee echa un vistazo a jQuery.param()http://api.jquery.com/jQuery.param/

Ejemplo:

var params = { 
    parameter1: 'value1', 
    parameter2: 'value2', 
    parameter3: 'value3' 
}; 
​var query = $.param(params); 
document.write(query); 
+10

¡Esta es en realidad la respuesta correcta! La cadena de consulta para un formulario es '$ .param ($ ('# myform'). SerializeArray())'. – Jesse

+7

@Jesse, ese sería el mismo resultado que: '$ ('# myform'). Serialize()' – cleaver

+65

'jQuery! == JavaScript' – gphilip

21

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

Es es probable que sea demasiado tarde para responder a su pregunta.
Tenía la misma pregunta y no me gustaba seguir añadiendo cadenas para crear una URL. Entonces, comencé a usar $ .param como techhouse explicado.
También encontré una biblioteca URI.js que crea las URL fácilmente para usted. Hay varios ejemplos que lo ayudarán: URI.js Documentation.
He aquí una de ellas:

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"]);` 
100

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('&'); 
+4

La mejor solución que he visto hasta ahora, muy limpia y concisa. Un par de advertencias, sin embargo. 1) en .map(), tanto k como params [k] deberían estar codificados, p. encodeURIComponent (k) y encodeURIComponent (params [k]). 2) Puede tener más de una instancia de un parámetro con nombre en una cadena de consulta. Si desea esa capacidad, deberá usar una matriz en lugar de un objeto (la mayoría de las aplicaciones no lo necesitarán o no). – user1738579

+5

3) No todos los navegadores admiten la sintaxis de la función de flecha (que requiere ES5). Si desea admitir todos los navegadores (y codificar las partes), reemplace el .map() anterior con .map (función (k) {return encodeURIComponent (k) + '=' + encodeURIComponent (params [k]);}) – user1738579

+1

Hermoso. Verdaderamente hermoso. –

5

querystring puede ayudar.

lo tanto, puede

const querystring = require('querystring') 

url += '?' + querystring.stringify(parameters) 
Cuestiones relacionadas