Ton*_*Abo 9 javascript ajax post internet-explorer
我最近发现,使用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标头.
我们经常在IE上遇到这个问题.没有好的解决方案.保证解决问题的唯一解决方案是确保Web服务器keepalive超时高于浏览器keepalive超时(默认情况下,IE为60s).Web服务器设置为较低值的任何情况都可能导致IE尝试重用连接并发送由TCP RST拒绝的请求,因为套接字已关闭.如果Web服务器keepalive超时值高于IE的keepalive超时,那么IE重用连接可确保套接字不会被关闭.对于高延迟连接,您必须考虑延迟时间,因为在传输过程中花费的时间可能是一个问题.
但请记住,增加服务器上的keepalive意味着空闲连接使用服务器套接字的时间要长得多.因此,您可能需要调整服务器的大小以处理大量不活动的空闲连接.这可能是一个问题,因为它可能导致服务器无法处理的服务器负载突发.
要记住的另一件事.您注意到RFC 8.1.4规定:"...客户端,服务器和代理必须能够从异步关闭事件中恢复.客户端软件应该重新打开传输连接并重新传输请求的中止序列,而无需用户交互. ".
你忘记了一个非常重要的部分.以下是全文:客户端软件应该重新打开传输连接,并在没有用户交互的情况下重新发送中止的请求序列,只要请求序列是幂等的(参见第9.1.2节).非幂等方法或序列绝不能自动重试,尽管用户代理可以为操作人员提供重试请求的选择.具有对应用程序的语义理解的用户代理软件的确认可以替代用户确认.如果第二个请求序列失败,则不应重复自动重试
HTTP POST是非幂等的,如9.1.2所定义.因此,根据RFC,注册表黑客的行为实际上在技术上是正确的.
不,通常 POST 在 IE 中有效。你所说的可能是一个问题,但这并不是一个值得发这么大的帖子的主要问题。
当您发出 POST ajax 请求时,为了确保涵盖每个浏览器不一致的情况,只需使用 jquery。
还有一件事:没有人会告诉你“使用其他浏览器”,因为 IE 被广泛使用并且需要照顾(好吧,除了 IE6 以及对于某些浏览器,甚至可能是一些较新的版本)
因此,POST必须在 IE 中工作,但为了避免意外的 bug 行为,使用 jquery 就可以睡个好觉了。
| 归档时间: |
|
| 查看次数: |
4657 次 |
| 最近记录: |