2011-12-30 6 views
5

Estoy usando jQuery para hacer llamadas ajax, muchas de las cuales funcionan bien, pero acabo de encontrar un problema extraño al intentar enviar una cadena al servidor. He reducido el código de abajo a esto:El objeto JavaScript String se divide en una matriz en jQuery.post

var x = new String('updateGroup'); 
var y = 'updateGroup'; 
$.post('page.aspx', { 
    f: x, 
    f2: y 
}, function(data) { 
}); 

Cuando se golpea el servidor sin embargo, las variables de petición son los siguientes:

Request["f"]   null   string 
Request["f2"]   "updateGroup" string 
Request.Form.AllKeys {string[12]} string[] 
    [0]     "f[0]"  string 
    [1]     "f[1]"  string 
    [2]     "f[2]"  string 
    [3]     "f[3]"  string 
    [4]     "f[4]"  string 
    [5]     "f[5]"  string 
    [6]     "f[6]"  string 
    [7]     "f[7]"  string 
    [8]     "f[8]"  string 
    [9]     "f[9]"  string 
    [10]    "f[10]"  string 
    [11]    "f2"   string 

donde Request["f[0]"] contiene "u" etc.

Puede alguien explica por qué sucede esto?

Respuesta

3

Si tirar todos los detalles, lo que está siendo ejecutado en su caso es:

  • jQuery.post
  • que llama a jQuery.ajax internamente para hacer el ajax
  • que llama internamente jQuery.param para generar la cadena de consulta

El punto es que new String no es una cadena primitivo, pero un objeto de cadena , y la voluntad pase la following check en jQuery.ajax (typeof new String("foo") === "object", no "string"):

// Convert data if not already a string 
if (s.data && s.processData && typeof s.data !== "string") { 
    s.data = jQuery.param(s.data, s.traditional); 
} 

jQuery.param está ejecutando as follows:

for (var prefix in a) { 
    buildParams(prefix, a[ prefix ], traditional, add); 
} 

Esto significa que hace un loop for in sobre la cadena, lo que de hecho pone a cada personaje por separado en la cadena de consulta.

Puede comprobar este comportamiento con este caso de prueba:

var x = new String("abc"); 

for(var i in x) { 
    console.log(i, x[i]); 
} 

// 0 "a" 
// 1 "b" 
// 2 "c" 
1

Cuando se utiliza nueva cadena se crea un objeto de cadena en lugar de una cadena en sí, si ejecuta esto en su navegador verá que son un objeto y una cadena con respeto:

console.log(typeof new String("hello")); 
console.log(typeof "hello"); 

Más información aquí (incluyendo por qué puede una matriz de caracteres publicados en el servidor): http://www.devguru.com/technologies/ecmascript/quickref/string.html

+0

Gracias - tiene sentido. Agregué .toString y .valueOf y ambos parecen solucionar el problema. Me parece extraño que Jquery trate los objetos de cuerdas de esta manera, parece contradictorio para mí. –

+0

El objeto String es una especie de reliquia arcaico, tiene métodos como grande, negrita, parpadeante, tipografía, fontcolor, etc., te da una buena idea de su edad ;-) – oodavid

1

JavaScript distinguishes between a literal string and an object of type String.
Sospecho que cuando el método de publicación jQuery está inspeccionando el objeto de datos que ha enviado, comprueba si typeof cada valor es string. Si es así, su trabajo está hecho. Si encuentra un Objeto (que es una Cadena) lo itera, por lo que está obteniendo una matriz de caracteres.

si tiene un objeto String puede utilizar String.valueOf() para obtener el valor simple

1

Nunca se debe crear una cadena como esta en javascript, se considera una mala práctica:

var x = new String('updateGroup'); 

pero siempre como este

var x = 'updateGroup'; 

porque en el primer caso se crea un objeto y sólo en el segundo caso se crea una cadena.Lo mismo ocurre con matrices, utilice siempre

var array = []; 
+0

Un sabio dijo una vez: no hagas instancias de variables triviales :-) +1 – Flater

+0

El objeto de cadena en sí viene de una capa de código de este ejemplo, aunque ahora estoy revisando esa capa para investigar de dónde viene. Me pregunto si realmente necesita ser una cadena. objeto en absoluto: se está construyendo a partir de .val() de un cuadro de entrada, pero no veo ninguna razón para que sea así, así que trataré de cambiar esa capa en lugar de que todos los que la usan tengan que preocuparse por usar valor de. –

Cuestiones relacionadas