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

Posted

技术标签:

【中文标题】为啥 Chrome 和 Firefox 以不同方式处理 jQuery ajax() 回调中设置的 javascript 变量?【英文标题】:Why do Chrome and Firefox handle javascript variable set inside jQuery ajax() callback differently?为什么 Chrome 和 Firefox 以不同方式处理 jQuery ajax() 回调中设置的 javascript 变量? 【发布时间】:2013-05-18 05:27:59 【问题描述】:

使用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(布尔值)。这是预期的行为吗?我很惊讶!

被解析的 JSON 是 data: ""result":false"

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

问题似乎出现在这里:

         var result = obj.result;
         status = result; 

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

【问题讨论】:

它解析的 JSON 是什么? 这没有任何意义 "false"false 之间的差异不可能更大。它们绝对不是一回事。 我希望您不会因为不想编写异步处理代码而锁定用户的浏览器。 你确定它实际上是false 并且不是在ff 中未定义吗?你能发布typeof status的输出吗? 我真的希望你没有死! :) 【参考方案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)  
       ... 

【讨论】:

status 是一个全局变量,默认存在于浏览器环境中(检查window.status,它用于设置状态栏文本)。我猜它实际上是 Chrome 中的 setter,而 setter 代码可能会自动将其转换为字符串。 有趣的是,这是问题所在,我同意 @bfavaretto 的观点,即它可能是状态栏属性,根据定义,它始终是一个字符串。 @bfavaretto 这是根本原因;我已经更新了我的答案。 @bfavaretto 如果您想将您的评论变成答案,我很乐意给您积分。 谢谢斯科特,但您的回答已经包含帮助未来访问者所需的所有信息。我很好奇可能导致此问题的原因,很高兴您添加了此答案以澄清这一点。另外,我相信您应该将此答案标记为“已接受”。【参考方案2】:

查看您的代码,肯定还有其他问题。在 Chrome 中,字符串"result":"false" 被正确接收、解析并显示它包含字符串false。在 Firefox 上,您的 XHR 调用似乎由于某种不明原因而失败,error 处理程序被调用,您自己显式执行status = false,从而导致它输出布尔值false。虽然这是对不同数据类型的唯一合乎逻辑的解释,但它不能解释为什么alert 调用不会显示错误框。可能是您在早期测试期间选中了“不允许此页面创建更多对话框”框?我很好奇当您将错误处理程序行更改为status = 684 而不是false 时,FF 中的输出是什么。

我们需要一个可重现的案例来进一步深入研究,所有其他 cmets 都表明 FF 和 Chrome 以相同的方式解析 JSON。

【讨论】:

错误处理程序没有被调用,因为警报没有出现。我可以在 Firebug 中跟踪代码并观察它通过成功路径。

以上是关于为啥 Chrome 和 Firefox 以不同方式处理 jQuery ajax() 回调中设置的 javascript 变量?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Firefox 对待 Helvetica 和 Chrome 的方式不同?

为啥 Chrome 和 Firefox 显示不同的 flex 布局结果?

为啥 Chrome 和 Firefox 使用基本身份验证的 CORS ajax 调用的行为不同?

为啥 IE 会以不同的方式呈现这个 HTML 表格?

为啥这个 HTML 在 Google Chrome 和 Firefox 中会产生两种不同的结果?

为啥 javascript 对象在 Chrome、Firefox、Safari 的控制台中显示不同的值? [复制]