失败后,为什么Internet Explorer在Ajax调用上不发送HTTP正文?


114

我们能够可靠地重新创建以下情况:

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

网络连接失败后,IE将发出下一个AJAX请求,但在执行HTTP发布时仅发送HTTP标头(而不是正文)。由于这只是部分请求,因此会在服务器上引起各种问题。Google与Bing有关此问题,您会发现很多人抱怨使用AJAX或“无法解释的AJAX故障”导致的“服务器随机错误”。

我们知道IE(与大多数其他浏览器不同)总是将HTTP POST作为两个TCP / IP数据包发送。标头和正文分别发送。在发生故障后,IE仅直接发送header。IE从不发送有效负载,服务器最终以超时响应。

所以我的问题是-为什么它会这样表现?基于HTTP规范,这似乎是错误的,其他浏览器却没有这种行为。这仅仅是一个错误吗?当然,这会在任何基于AJAX的严重Web应用程序中造成严重破坏。

参考信息:

还有一个类似的问题,是由少于1分钟的HTTP保持活动超时触发的,记录在这里:

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


6
这是一个很好的,定义明确的问题,值得回答。不幸的是,这有点离题。我不确定webmasters.stackexchange.comsuperuser.stackexchange.com上是否会更好。
斯蒂芬

3
@ gilly3,我认为我一定有问题,因为我读了那句话,只是随便点点头……
Ryley

1
@ gilly3:当翻译成荷兰语时,这是正确的,因为“ googelen”是一个动词(甚至在荷兰语词典中已定义),意思是在荷兰语中“搜索网络”。是的,它的拼写是“ googelen”而不是“ googlen”。奇怪,我知道。因此,您可以说:“高格尔遇到问题时碰到了必应。” 这是正确的。

11
@ gilly3:Bing是什么?我要去谷歌。
火箭Hazmat

5
“为什么会这样?” -您会接受一个答案吗?“尽管Microsoft员工在很大程度上是杰出的,但他们是一种编程文化的一部分,这种编程文化与我们通过DEC,Unix,Apple,Commodore或其他背景进入数字时代的人们根本不同,并倾向于做使我们其余人惊讶的事情,而不是惊讶于他们的光辉,而是因为他们过于复杂和完全腐化了对我们其余人来说简单明了的事物。”
jcomeau_ictx 2011年

Answers:


28

这个问题似乎没有明确的答案,因此我将提供经验数据作为替代,并提供一些解决方法。也许某些MS内部人士有一天会对此有所了解...

  1. 如果在服务器上禁用了HTTP Keep-Alive ,则此问题将消失。换句话说,您的HTTP 1.1服务器将响应每个Ajax请求,Connection: Close并在响应中添加一行。这使IE保持快乐,但会导致每个Ajax请求打开一个新连接。这可能会对性能产生重大影响,尤其是在高延迟网络上。

  2. 如果快速连续提出Ajax请求,则很容易触发该问题。例如,我们每100ms发出一次Ajax请求,然后网络状态发生变化,该错误很容易重现。尽管大多数应用程序可能不会发出这样的请求,但是您可能会接连发生几次服务器调用,这可能导致此问题。较少的聊天使IE保持快乐。

  3. 即使没有NTLM身份验证,它也会发生。

  4. 当服务器上的HTTP保持活动超时时间短于默认值(在Windows上默认为60秒)时,就会发生这种情况。相关链接中提供的详细信息。

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

  6. 它发生在IE 6、7、8中。无法在IE 9 beta中复制。


4
还有其他方法可以解决此问题吗?任何JavaScript修复?我尝试查看各种XMLHTTP对象,但它们仍然无法解决问题。
柏林·布朗

11

标题为“ 当您使用Microsoft Internet Explorer或其他程序执行重新发布操作时 ”的Microsoft KB文章似乎仅发布了标头数据即可解决此问题。

本文提供了一个修复程序。对于更高版本的浏览器(例如IE8),它表示已包含此修复程序,但需要通过客户端PC上的注册表设置启用该修复程序。


1
我正在使用IE10遇到此问题,本文未提及。
2013年

6
现在,本文最多提到IE11,因此似乎从未修复过。
农民

我相信我正在生产站点上遇到此问题-与该问题相关的用户代理对应于IE 8,9,10和
11。– millhouse 2015年

有没有人找到解决方法?具体来说,我发送了307和FF,Chrome,Safari将数据重新发布到了新的端点-IE没有。我不能要求我的用户修补程序/注册表补丁。
布拉德·冈恩

2

我有一个类似的问题,即某些旧版本的IE只会发回标头,而不会发回POST正文。我的问题原来与IE和NTLM有关。由于您没有提到NTLM,所以这可能无济于事,以防万一:

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


您的链接在IE 11解决类似的问题,是有益的和IIS 6
Harminder

1

这是一个漫长的过程,但是IE(甚至Firefox)有时会“记住”它用于HTTP请求的连接。注释/示例:

  • 在Firefox中,如果我更改代理设置并在页面上按SHIFT-RELOAD,它仍会使用旧的代理。但是,如果我杀死了旧的代理(“ killall squid”),它将开始使用新的代理。

  • 断开/重新连接时,您会收到一个新的IP地址或类似的东西吗?您能以某种方式监视旧IP地址以查看IE是否正在将数据发送到该已失效的地址吗?

  • 我的猜测是IE正在沿错误的路径发送数据。不为“ POST”数据包缓存网络连接可能足够聪明,但是对于POST负载则可能不够聪明。

  • 这可能不会影响大多数AJAX应用,因为人们很少断开并重新连接到他们的网络?


2
我认为问题是最后一个。我认为微软使用“很少发生:不实施”政策。:)

1
我监视从源到目标的所有HTTP通信。我可以确认(a)我的IP地址没有更改,并且(b)没有尝试发送其他任何内容。IE打开一个新的套接字并发送部分请求。我阅读MS文章的方式,是他们打破IE的安全更新之一。然后,他们创建了一个补丁来解决该问题。但是,以防万一您希望它表现出旧的“断”方式,您可以添加此注册表项。Retry_HeaderOnlyPOST_OnConnectionReset。只是想弄清楚疯狂。
2011年

最后一点:如果您有一个定期(例如10秒)轮询的Ajax应用程序,我们发现如果将其打开几个小时,则总是会发生此错误。可能是Wi-Fi连接掉线或网络粗略-但是我们的经验是这个问题非常真实。
Dodgyrabbit 2011年

1

您正在使用NTLM身份验证吗?

使用NTLM身份验证时,IE不会发送后数据。它发送标题信息,期望未经授权的响应发送授权,并且在“重新认证”之后发送帖子。


我们不使用NTLM身份验证。发生匿名请求。
Dodgyrabbit 2011年

0

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.