为什么 Chrome 和 Firefox 以不同的方式处理 jQuery ajax() 回调中设置的 javascript 变量?

Sco*_*son 1 javascript firefox jquery google-chrome

使用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) {
        ....
Run Code Online (Sandbox Code Playgroud)

我发现 Chrome 会返回状态“false”(字符串),而 Firefox 会返回状态 false(布尔值)。这是预期的行为吗?我惊呆了!

正在解析的 JSON 是数据:"{"result":false}"

typeof(status) 在 Chrome 中是字符串,在 FF 中是布尔值。

问题似乎出现在这里:

         var result = obj.result;
         status = result; 
Run Code Online (Sandbox Code Playgroud)

因为Chrome中result的数据类型是boolean,而status的数据类型是string。

调试器中显示的变量更改

Sco*_*son 5

知道了。问题是在声明状态之前缺少“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
   ...
Run Code Online (Sandbox Code Playgroud)

另一种编码方式是

    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) { 
       ... 
Run Code Online (Sandbox Code Playgroud)

可能最好的做法是不要重用现有的变量名称状态,因此使用第二个示例,这将给出

    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) { 
       ... 
Run Code Online (Sandbox Code Playgroud)

  • `status` 是一个全局变量,默认存在于浏览器环境中(检查 `window.status`,它用于设置状态栏文本)。我猜它实际上是 Chrome 中的一个 setter,并且 setter 代码可能会自动将其转换为字符串。 (2认同)