为什么Internet Explorer在失败后不会在Ajax调用上发送HTTP post body?

时间:2011-01-25 16:44:40

标签: javascript ajax internet-explorer

我们能够可靠地重建以下场景:

  1. 创建一个小型HTML页面,向服务器发出AJAX请求(使用HTTP POST)
  2. 断开网络连接并重新连接
  3. 监视IE失败后生成的数据包
  4. 在网络连接失败后,IE会发出下一个AJAX请求,但在执行HTTP发布时只发送 HTTP标头(不是正文)。这会导致服务器上出现各种问题,因为它只是部分请求。谷歌与Bing的这个问题,你会发现很多人抱怨使用AJAX或无法解释的AJAX失败的“随机服务器错误”。

    我们知道IE(与大多数其他浏览器不同)总是将HTTP POST作为TWO TCP / IP数据包发送。标题和正文是分开发送的。在失败后的情况下, IE仅发送标题

    所以我的问题是 - 它为什么会这样?基于HTTP规范似乎是错误的,其他浏览器不会这样做。这只是一个错误吗?当然,这会在任何基于AJAX的严肃Web应用程序中造成严重破坏。

    参考信息:

    有一个类似的问题,由超过1分钟的HTTP保持活动超时触发,并在此处记录:

    http://us.generation-nt.com/xmlhttprequest-post-sometimes-fails-when-server-using-keep-aliv-help-188813541.html

    http://support.microsoft.com/default.aspx?kbid=831167

    以下是失败数据包捕获之前和之后:

    注意HTTP Header和Payload是如何发送的 http://img827.imageshack.us/i/beforee.png/

    失败后,请注意如何仅发送标头。 IE 从不发送有效负载,服务器最终以超时响应。 http://img203.imageshack.us/i/retryt.png/

6 个答案:

答案 0 :(得分:27)

这个问题似乎没有明确的答案,因此我将提供我的经验数据作为替代,并提供一些解决方法。也许有些MS内幕人士有一天会对此有所了解......

  1. 如果服务器上的HTTP Keep-Alive 禁用,此问题就会消失。换句话说,您的HTTP 1.1服务器将响应响应中Connection: Close行的每个Ajax请求。这使IE保持高兴,但会导致每个Ajax请求打开一个新连接。这会对性能产生重大影响,尤其是在高延迟网络上。

  2. 如果快速连续发出Ajax请求,则很容易触发该问题。例如,我们每100毫秒发出一次Ajax请求,然后网络状态发生变化,错误很容易重现。虽然大多数应用程序可能不会发出此类请求,但您可能会在一个接一个的服务器调用之后发生,这可能会导致此问题。不那么讨厌让IE很开心。

  3. 即使没有NTLM身份验证,也会发生这种情况。

  4. 当服务器上的HTTP保持活动超时短于默认值(Windows上默认为60秒)时,会发生这种情况。有关链接中提供的详细信息。

  5. Chrome或Firefox不会发生这种情况。 FF发送一个数据包,所以似乎完全避免了这个问题。

  6. 它发生在IE 6,7,8中。无法用IE 9 beta重现。

答案 1 :(得分:11)

名为 When you use Microsoft Internet Explorer or another program to perform a re-POST operation, only the header data is posted 的微软KB文章似乎解决了这个问题。

本文提供了一个修补程序。对于IE8等后来的浏览器,它说修补程序已经包含但需要通过客户端PC上的注册表设置启用

答案 2 :(得分:2)

我遇到了类似的问题,其中一些旧版本的IE只发送回Header而不是POST的正文。我的问题结果与IE和NTLM有关。既然你没有提到NTLM,这可能没有帮助,但以防万一:

http://support.microsoft.com/kb/251404

答案 3 :(得分:1)

这是一个远景,但IE(甚至Firefox)有时“记得” 它用于HTTP请求的连接。注释/示例:

  • 在Firefox中,如果我更改了代理设置并点击了SHIFT-RELOAD 一个页面,它仍然使用旧代理。但是,如果我杀了旧的 代理(“killall squid”),它开始使用新代理。

  • 断开/重新连接时,是否收到新的IP地址或 什么类似的?你能以某种方式监视旧的IP地址,看看 如果IE正在向那个已经死亡的地址发送数据?

  • 我的猜测是IE正在发送数据,只是错误 路径。它可能足够聪明,不能缓存网络连接 “POST”数据包,但可能不够聪明,无法为POST执行此操作 有效载荷。

  • 这可能不会影响大多数AJAX应用程序,因为人们很少 断开连接并重新连接到他们的网络?

答案 4 :(得分:1)

您使用的是NTLM身份验证吗?

使用NTLM身份验证时,IE不会发送后期数据。它发送标题信息,期望未经授权的响应发送授权,并在“重新认证”发送帖子后。

答案 5 :(得分:-1)

今天我在使用$ .ajax时遇到了类似的问题,并且能够通过将async设置为false来修复它。



$.ajax({
  async: false, 
  url: '[post action url]',
  data: $form.serialize(),
  type: 'POST',
  success: successCallback
});