1
votes

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.

variable change shown in debugger

2
What's the JSON it's parsing?Mike Christensen
That doesn't make any sense the difference between "false" and false couldn't be bigger. They're absolutely not the same thing.Halcyon
I hope you're not locking your users' browsers because you don't want to write asynchronous handling code.alex
Are you sure it's actually false and not undefined in ff? Could you post the output of typeof status?bfavaretto
I really hope you're not dying! :)bfavaretto

2 Answers

5
votes

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) { 
       ... 
1
votes

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.