上周我一直在跟踪我自己的应用程序中的类似问题(使用 Dojo,而不是 JQuery)。根据您的描述和发生频率,我会说这是同一个问题。
当浏览器和服务器之间使用 HTTP 持久连接时(默认行为),服务器可以随时关闭 HTTP 连接。这会在浏览器开始发送新请求的同时服务器关闭连接时创建一个非常小的计时漏洞。大多数浏览器将使用不同的连接或打开新连接并重新发送请求。这是 RFC 2616 第 8.1.4 节中建议的行为:
客户端、服务器或代理可以随时关闭传输连接。例如,客户端可能在服务器决定关闭“空闲”连接的同时开始发送新请求。从服务器的角度来看,连接是在空闲时关闭的,但从客户端的角度来看,请求正在进行中。
这意味着客户端、服务器和代理必须能够从异步关闭事件中恢复。只要请求序列是幂等的,客户端软件应该重新打开传输连接并重新传输中止的请求序列,而无需用户交互(参见第 9.1.2 节)。
发生这种情况时,Internet Explorer确实会尝试重新发送请求,但是当它恰好是 POST 时,它会通过发送标头(带有 Content-Length)而不是实际数据来破坏它。这是一个格式错误的请求,应该总是导致 HTTP 错误(通常在等待永远不会到来的数据超时之后)。
Microsoft 将此错误记录为 KB 895954(请参阅http://support.microsoft.com/kb/895954)。微软首先在 IE 6 中发现了这个错误。他们提供了一个修补程序,并且从那时起,包括 IE 9 在内的每个版本的 IE 似乎都提供了这个修补程序。这个修复程序有两个问题:
默认情况下不激活此修补程序。您必须使用 regedit 创建一个非常奇怪的密钥来激活修复程序:HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SKIP_POST_RETRY_ON_INTERNETWRITEFILE_KB895954。
修复并不能真正解决问题。“固定”行为是当尝试发送请求时连接关闭时,它甚至不会尝试重新发送它。它只是将错误传递给 javascript 应用程序。
看来您必须在代码中添加错误处理程序,并在失败时自己重新发布请求。我正在为我的应用程序寻找这个解决方案。我担心的是,我不确定如何判断我得到的错误是由尝试发送查询失败引起的,还是由于查询而从服务器发回的某些错误(在这种情况下我不知道)想重发)。
我编写了一个 C 程序来模拟 Web 服务器并显式关闭连接以查看浏览器如何处理它。我发现 IE 可以 100% 的时间重现错误行为,而 Firefox、Safari 和 Chrome 可以通过在另一个连接上 100% 的时间正确重新发送 POST 来恢复。也许答案是“不要使用 IE”。