Почему Chrome и Firefox обрабатывают переменную javascript внутри jQuery ajax() по-разному?

Использование jQuery 1.9.1, обращаясь к серверу, чтобы проверить некоторые данные:

    $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) {
        ....

Я обнаружил, что Chrome вернет статус "false" (строка), и Firefox вернет статус false (boolean). Это ожидаемое поведение? Я был поражен!

Анализируемый JSON - это данные: "{" result ": false}"

typeof (status) - строка в Chrome и boolean в FF.

Проблема, кажется, возникает здесь:

         var result = obj.result;
         status = result; 

Поскольку тип данных результата в Chrome является логическим, тогда как тип данных статуса является строкой.

variable change shown in debugger

Ответ 1

Получил это. Проблема заключалась в отсутствии "var" перед объявлением статуса.

Как указано ниже, @bfavaretto, статус уже определен как глобальная переменная. Поэтому, если бы я использовал переменную с именем "ajax_status", мне было бы хорошо без var или я мог бы использовать имя переменной "status", но мне пришлось бы сделать ее локальной (с использованием var).

Следующий код работает как чемпион в FF и 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
   ...

Другим способом кодирования этого будет

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

и, вероятно, лучшей практикой было бы не повторно использовать существующее имя имени переменной, поэтому, используя второй пример, это даст

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

Ответ 2

Глядя на ваш код, должно быть что-то еще не так. В Chrome строка {"result":"false"} правильно получена, проанализирована и показана, что она содержит строку false. В Firefox ваш XHR-вызов, по-видимому, терпит неудачу по какой-то неопознанной причине, вызывается обработчик error, где вы явно выполняете status = false, что приводит к выводу логического false. Хотя это единственное логическое объяснение для разных типов данных, оно не объясняет, почему вызов alert не будет показывать окно ошибки. Возможно, вы отметили флажок "Не разрешать эту страницу для создания большего количества диалогов" во время более раннего тестирования? Мне любопытно, какой результат в FF, когда вы меняете эту строку с ошибкой на status = 684 вместо false.

Нам понадобится воспроизводимый случай где-то, чтобы погрузиться в это дальше, все остальные комментарии показали, что FF и Chrome одинаково разбирают JSON.