Perché Chrome e Firefox gestiscono la variabile javascript impostata all’interno della callback jQuery ajax () in modo diverso?

Usando jQuery 1.9.1, richiamando il server per controllare alcuni dati:

$form = $("#form2") var str = $form.serialize(); status = true; $.ajax({ type : 'POST', url : 'check_zip.php', data : str, async : false, success : function (data) { obj = JSON.parse(data); var result = obj.result; status = result; }, error : function (msg) { alert(msg); status = false; } }); if (status == "false" || status === false) { .... 

Ho scoperto che Chrome restituiva lo stato “false” (stringa) e Firefox restituiva lo stato false (booleano). È questo comportamento previsto? Sono rimasto stupito!

Il JSON analizzato è data: “{” result “: false}”

typeof (status) è una stringa in Chrome e boolean in FF.

Il problema sembra sorgere qui:

  var result = obj.result; status = result; 

Poiché il tipo di dati del risultato in Chrome è booleano, mentre il tipo di dati dello stato è stringa.

modifica variabile mostrata nel debugger

Fatto. Il problema era la “var” mancante prima della dichiarazione di stato.

Come @bfavaretto indicato di seguito, lo stato è già definito come variabile globale. Quindi se avessi usato una variabile chiamata “ajax_status” sarei andato bene senza la var o avrei potuto usare il nome della variabile “status”, ma avrei dovuto renderlo locale (usando var).

Il seguente codice funziona come un champ sia in FF che in Chrome.

 $form = $("#form2") var str = $form.serialize(); var status = true; // <--- change 1 - use "var" $.ajax({ type : 'POST', url : 'check_zip.php', data : str, async : false, success : function (data) { obj = JSON.parse(data); var result = obj.result; status = result; }, error : function (msg) { alert(msg); status = false; } }); if (status === false) { // <-- change 2 - just use boolean comparison ... 

Un altro modo per codificare questo sarebbe

  var ajaxreturn = $.ajax({ type : 'POST', url : 'check_zip.php', data : str, async : false, success : function (data) { }, error : function (msg) { alert("Unexpected server response on zip validation"); } }); var status = false; try { obj = JSON.parse(ajaxreturn.responseText); status = obj.result; } catch (e) { status = false; } if (status === false) { ... 

e probabilmente la migliore pratica sarebbe non riutilizzare lo stato del nome della variabile esistente, quindi usando il secondo esempio, questo darebbe

  var ajaxreturn = $.ajax({ type : 'POST', url : 'check_zip.php', data : str, async : false, success : function (data) { }, error : function (msg) { alert("Unexpected server response on zip validation"); } }); var check_status = false; try { obj = JSON.parse(ajaxreturn.responseText); check_status = obj.result; } catch (e) { check_status = false; } if (check_status === false) { ... 

Guardando il tuo codice, ci deve essere qualcos’altro che non va. In Chrome, la stringa {"result":"false"} viene correttamente ricevuta, analizzata e mostrato che contiene la stringa false . Su Firefox, la tua chiamata XHR sembra fallire per qualche motivo non identificato, viene invocato il gestore degli error , dove tu stesso esegui esplicitamente status = false , ottenendo così l’output del false booleano. Anche se questa è l’unica spiegazione logica per il diverso tipo di dati, non spiega perché la chiamata di alert non mostrerebbe una finestra di errore. Potrebbe essere che hai controllato la casella “Non permettere a questa pagina di creare più windows di dialogo” durante i test precedenti? Sono curioso di sapere quale sia l’output in FF quando cambi la riga di errorhandler in status = 684 invece di false .

Avremmo bisogno di un caso riproducibile da qualche parte per approfondire ulteriormente, tutti gli altri commenti hanno indicato che FF e Chrome analizzano il JSON in modo identico.