我最近发现,使用Internet Explorer运行我的应用程序的用户间歇性故障的问题是由于Internet Explorer中的错误.该错误位于HTTP堆栈中,应该使用来自IE的POST请求影响所有应用程序.结果是失败的特征是请求似乎挂起约5分钟(取决于服务器类型和配置),然后从服务器端失败.服务器放弃后,浏览器应用程序将在post请求中出错.我将在下面详细解释IE错误.
据我所知,如果请求是在错误的时刻发送的,那么使用XMLHttpRequest将POST请求发送到服务器的任何应用程序都会发生这种情况.我编写了一个示例程序,试图在这些时间发送POSTS.它会尝试在服务器关闭连接的精确时刻向服务器发送连续的POST.间隔源自服务器发送的Keep-Alive标头.
我发现当从IE运行到具有一点延迟的服务器(即不在同一个LAN上)时,问题只发生在几个POST之后.当它发生时,IE锁定得如此之难以至于必须强制关闭.滴答时钟表示浏览器仍在响应.
您可以通过浏览到http://pubdev.hitech.com/test.post.php来尝试.请注意,在运行任何IE会话时,您没有任何重要的未保存信息,因为我发现它会导致IE崩溃.
完整的源代码可以在以下网址获取:http://pubdev.hitech.com/test.post.php.txt.您可以在任何具有php并配置为持久连接的服务器上运行它.
我的问题是:
其他人对此问题的体验是什么?
是否有解决此问题的已知策略("使用其他浏览器"除外)?
微软是否比我找到的文章(见下文)有更好的信息?
问题是Web浏览器和服务器默认使用持久连接,如RFC 2616第8.1节所述(请参阅http://www.ietf.org/rfc/rfc2616.txt).这对性能非常重要 - 特别是对于AJAX应用程序 - 并且不应禁用.然而,在服务器决定连接空闲并决定关闭它的同时,浏览器可能开始在先前使用的连接上发送POST的小定时孔.结果是浏览器的HTTP堆栈将出现套接字错误,因为它使用的是封闭套接字.RFC 2616第8.1.4节预见到了这种情况,并指出"......客户端,服务器和代理必须能够从异步关闭事件中恢复.客户端软件应该重新打开传输连接并重新传输请求的中止序列,而无需用户交互......"
发生这种情况时,Internet Explorer 会重新发送POST,但是当它发生时,它会破坏请求.它发送POST标头,包括发布的数据的Content-Length,但它不发送数据.这是一个不正确的请求,服务器将在请求失败之前等待未指定的时间用于承诺的数据.我已经能够使用模拟HTTP服务器的C程序100%地演示此失败,该服务器关闭传入POST请求的套接字而不发送响应.
Microsoft似乎在http://support.microsoft.com/kb/895954中承认此失败 .他们说它影响了IE版本6到9.这提供了一个针对此问题的修补程序,自IE 7以来已经附带了IE的所有版本.由于以下原因,此修补程序似乎不满意:
除非您使用regedit将名为FEATURE_SKIP_POST_RETRY_ON_INTERNETWRITEFILE_KB895954的密钥添加到注册表,否则不会启用它.这不是我希望用户必须做的事情.
此修补程序实际上不会修复损坏的POST.相反,如果套接字按照RFC的预期关闭,它只会立即出错,而不会尝试重新发送POST.应用程序仍然失败 - 它只是更快失败.
以下示例是一个自包含的php程序,用于演示该错误.它会尝试在服务器关闭连接的精确时刻向服务器发送连续的POST.间隔源自服务器发送的Keep-Alive标头.