Why does Internet Explorer not send HTTP post body on Ajax call after failure?

我们能够可靠地重现以下情景:

  1. 创建一个小的 HTML 页面,向服务器发出 AJAX 请求(使用 HTTPPOST)
  2. 断开网络并重新连接
  3. 监视 IE 在故障后生成的数据包

在网络连接失败后,IE 发出下一个 AJAX 请求,但在发送 HTTP 消息时只发送 HTTP 头(而不是主体)。这会导致服务器上出现各种各样的问题,因为它只是部分请求。用 Bing 搜索这个问题,你会发现很多人抱怨使用 AJAX 或无法解释的 AJAX 故障导致“随机服务器错误”。

我们知道 IE (不像大多数其他浏览器)总是以两个 TCP/IP 数据包的形式发送一个 HTTP POST。标头和正文分别发送。在这种情况下直接失败后,IE 只发送头文件。IE 从不发送负载,服务器最终会响应一个超时。

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

参考资料:

还有一个类似的问题,由 HTTP keep-alive 超时触发,超时时间短于1分钟,这里有文档说明:

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

47851 次浏览

This is a longshot, but IE (and even Firefox) sometimes "remembers" 它用于 HTTP 请求的连接。注释/示例:

  • 在 Firefox 中,如果我更改代理设置并点击 SHIFT-RELOAD a page, it still uses the old proxy. However, if I kill the old proxy ("killall squid"), it starts using the new proxy.

  • 断开/重新连接时,是否收到新的 IP 地址或 有没有类似的东西? 你能不能监控一下旧的 IP 地址 如果 IE 正在将数据发送到那个现已死亡的地址?

  • My guess is that IE is sending the data, just down the wrong 它可能足够聪明,不缓存网络连接 “ POST”数据包,但可能不够聪明,不能为 POST 这样做 有效载荷

  • 这可能不会影响大多数 AJAX 应用程序,因为人们很少 disconnect and re-connect to their networks?

我也遇到过类似的问题,一些旧版本的 IE 只返回头部,而不返回 POST 的主体。我的问题被证明与 IE 和 NTLM 有关。由于你没有提到 NTLM,这可能没有帮助,但以防万一:

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

Are you using NTLM authentication?

在使用 NTLM 身份验证时,IE 不发送后期数据。它发送头信息,期望未经授权的响应发送授权,并在重新认证后发送文章。

There does not seem to be a clear answer to this question, so I will provide my empirical data as a substitute and provide some ways to work around it. Maybe some MS insider will one day shed some light on this...

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

  2. 如果快速连续地发出 Ajax 请求,就很容易触发这个问题。例如,我们每隔100毫秒进行一次 Ajax 请求,然后网络状态发生变化,错误很容易重现。尽管大多数应用程序可能不会发出这样的请求,但是您可能会有几个服务器调用紧接着发生,这可能会导致这个问题。少说话能让 IE 高兴。

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

  4. It happens when your HTTP keep-alive timeout on the server is shorter than the default (which defaults to 60 seconds on Windows). Details provided in link in question.

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

  6. 这种情况发生在 IE6,7,8中,IE9 beta 版本无法重现。

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

The article provides a hotfix. For later browsers such as IE8 it says the hotfix is already included 但需要启用 through the registry settings on the client PC.

我今天在使用 $. ajax 时也遇到了类似的问题,我能够通过将 sync 设置为 false 来解决这个问题。

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