Why do Chrome and Firefox handle javascript variable set inside jQuery ajax() callback differently?
Using jQuery 1.9.1, calling back to the server to check some data:
$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) {
....
I found that Chrome would return status "false" (string) and Firefox would return status false (boolean). Is this expected behavior? I was astonished!
The JSON being parsed is data: "{"result":false}"
typeof(status) is string in Chrome and boolean in FF.
The issue seems to arise here:
var result = obj.result;
status = result;
Because the datatype of result in Chrome is boolean, whereas the datatype of status is string.
Got it. The issue was the missing "var" before the declaration of status.
As @bfavaretto noted below, status is already defined as a global variable. So if I had used a variable named like "ajax_status" I would have been fine without the var or I could have used the "status" variable name, but would have had to make it local (using var).
The following code works like a champ in both FF and 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
...
Another way to code this would be
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) {
...
and probably the best practice would be not to reuse the existing variable name status, so using the second example, this would give
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) {
...
Looking at your code, there must be something else going wrong. In Chrome, the string {"result":"false"}
is correctly received, parsed, and shown that it contains the string false
. On Firefox, your XHR call appears to fail for some unidentified reason,, the error
handler is invoked, where you yourself explicitly execute status = false
, thus resulting in it outputting the boolean false
. Whilst this is the only logical explanation for the different data type, it does not explain why the alert
call wouldn't be showing an error box. It could be that you checked the "Do not allow this page to create more dialogs" box during earlier testing? I'm curious what the output in FF is when you change that errorhandler line to status = 684
instead of false
.
We would need a reproducible case somewhere to dive into this further, all other comments have indicated that FF and Chrome parse the JSON identically.
链接地址: http://www.djcxy.com/p/2852.html下一篇: 为什么Chrome和Firefox处理jQuery ajax()回调中的javascript变量集的方式不同?