2011-12-30 12 views
5

Sto usando jQuery per effettuare chiamate ajax - molte delle quali funzionano bene, ma ho appena incontrato un problema strano nel tentativo di inviare una stringa al server. Ho ristretto il codice fino a solo questo:L'oggetto stringa JavaScript viene diviso in un array su jQuery.post

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

Quando colpisce il server tuttavia, le variabili di richiesta sono i seguenti:

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 

dove Request["f[0]"] contiene "u" ecc

Can qualcuno spiega perché succede?

risposta

3

Se buttare via tutti i dettagli, ciò che è stato giustiziato nel tuo caso è:

  • jQuery.post
  • che chiama jQuery.ajax internamente per fare l'ajax
  • che chiama jQuery.param internamente per costruire la stringa di query

Il punto è che new String non è una stringa primitivo ma una stringa oggetto, e sarà passaggio il following check in jQuery.ajax (typeof new String("foo") === "object", non "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 è l'esecuzione as follows:

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

Ciò significa che esegue un ciclo for in sulla stringa, che in effetti inserisce ciascun carattere separatamente nella stringa di query.

È possibile controllare questo comportamento con questo TestCase:

var x = new String("abc"); 

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

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

Quando si utilizza new String si crea un oggetto stringa piuttosto che una stringa stessa, se si esegue questo nel tuo browser si vedrà che sono un oggetto e una stringa con rispetto:

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

Altro informazioni qui (compreso il motivo per cui è possibile un array di caratteri inviati ad server): http://www.devguru.com/technologies/ecmascript/quickref/string.html

+0

Grazie - ha un senso. Ho aggiunto un .toString e .valueOf ed entrambi sembrano aggirare il problema. Mi sembra strano che Jquery tratti gli oggetti a corda in questo modo - mi sembra poco intuitivo. –

+0

L'oggetto String è un po 'una reliquia arcaica, ha metodi come big, bold, blink, fontsize, fontcolor etc. ti dà una buona idea della sua età ;-) – oodavid

1

JavaScript distinguishes between a literal string and an object of type String.
Sospetto che quando il metodo jQuery post sta ispezionando l'oggetto dati che è stato inviato, controlla se il valore typeof è string. Se lo è, il suo lavoro è finito. Se trova un oggetto (che è una stringa) itera su di esso - che è il motivo per cui stai ricevendo una serie di caratteri.

se si dispone di un oggetto String è possibile utilizzare String.valueOf() per ottenere il valore di base

1

Non si dovrebbe mai creare una stringa come questo in javascript, è considerato una cattiva pratica:

var x = new String('updateGroup'); 

ma sempre come questo

var x = 'updateGroup'; 

perché nel primo caso si crea un oggetto e solo nel secondo caso si crea una stringa.Lo stesso vale per gli array, utilizzare sempre

var array = []; 
+0

Un uomo saggio una volta disse: non fare esempi di variabili banali :-) +1 – Flater

+0

L'oggetto stringa stesso proviene da un livello di codice lontano da questo esempio, anche se ora sto rivisitando quel livello per indagare da dove proviene Mi chiedo se in realtà debba essere una stringa oggetto - è stato costruito dal valore .val() di una casella di input, ma non vedo alcun motivo per farlo in questo modo, quindi guarderemo a cambiare quel livello invece di tutti quelli che lo usano dovendo preoccuparsi di usare valore di. –