据我所知,只要在错误的时刻发送请求,任何使用XMLHttpRequest发送POST请求到服务器的应用程序都会发生这种情况。我编写了一个示例程序,试图在服务器关闭连接的精确时刻连续向服务器发送POST。时间间隔是从服务器发送的Keep-Alive头派生的。
我发现,当从IE运行到具有一定延迟的服务器上(即不在同一局域网上)时,只需几个POSTs就会出现问题。当它发生时,IE会锁定得如此之紧,以至于必须强制关闭。滴答声表明浏览器仍在响应。
您可以通过浏览以下链接来尝试:http://pubdev.hitech.com/test.post.php。请注意,在运行此程序时,请确保您的IE会话中没有任何重要的未保存信息,因为我发现它会导致IE崩溃。
完整源代码可在以下链接中检索:http://pubdev.hitech.com/test.post.php.txt。您可以在任何配置了PHP和持久连接的服务器上运行它。
我的问题是:
其他人对这个问题有什么经验吗?
除了“使用另一个浏览器”之外,是否有已知的解决此问题的策略?
微软是否有比我找到的文章更好的关于这个问题的信息?
Internet Explorer在这种情况下确实会重新发送POST请求,但它在这样做时会搞乱请求。它发送POST头,包括已发布数据的Content-Length,但不发送数据。这是一个不正确的请求,服务器将在等待承诺的数据之前等待未指定的时间,然后用错误失败请求。我已经能够使用模拟HTTP服务器的C程序100%演示此故障,并关闭传入POST请求的套接字而不发送响应。
Microsoft似乎在http://support.microsoft.com/kb/895954中承认了这个问题。他们说它影响IE 6到9版本。提供了解决此问题的热修复程序,该程序已随所有IE版本一起发布自IE 7以来。以下原因使热修复程序似乎不令人满意:
除非您使用regedit添加名为FEATURE_SKIP_POST_RETRY_ON_INTERNETWRITEFILE_KB895954的密钥到注册表中,否则它不会启用。这不是我希望我的用户必须做的事情。
热修补程序实际上并没有修复损坏的POST。相反,如果套接字按RFC预期关闭,则立即出错而不尝试重新发送POST。应用程序仍然失败 - 只是失败得更快。
以下示例是一个自包含的PHP程序,演示了该错误。它试图在服务器关闭连接的精确时刻连续发送POST。间隔是从服务器发送的Keep-Alive标头派生的。