Javascript 为什么 Internet Explorer 在 Ajax 调用失败后不发送 HTTP 帖子正文?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4796305/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does Internet Explorer not send HTTP post body on Ajax call after failure?
提问by Dodgyrabbit
We are able to reliably recreate the following scenario:
我们能够可靠地重新创建以下场景:
- Create a small HTML page that makes AJAX requests to a server (using HTTP POST)
- Disconnect from the network and reconnect
- Monitor the packets that IE generates after the failure
- 创建一个小的 HTML 页面,向服务器发出 AJAX 请求(使用 HTTP POST)
- 断开网络并重新连接
- 监控IE失败后生成的数据包
After a failed network connection, IE makes the next AJAX request but only sends the HTTP header(not the body) when doing the HTTP post. This causes all sorts of problems on the server as it is only a partial request. Google this issue with Bing and you'll find lots of people complaining about "random server errors" using AJAX or unexplained AJAX failures.
网络连接失败后,IE 发出下一个 AJAX 请求,但在执行 HTTP 发布时仅发送HTTP 标头(而不是正文)。这会导致服务器出现各种问题,因为它只是部分请求。用 Bing 搜索这个问题,你会发现很多人抱怨使用 AJAX 的“随机服务器错误”或无法解释的 AJAX 故障。
We know that IE (unlike most other browsers) always sends an HTTP POST as TWO TCP/IP packets. The header and body is sent separately. In the case directly after a failure, IE only sends the header. IE never sends the payload and the server eventually responds with a Timeout.
我们知道 IE(与大多数其他浏览器不同)总是将 HTTP POST 作为两个 TCP/IP 数据包发送。标头和正文分开发送。在直接失败后的情况下,IE 只发送 header。IE 从不发送有效负载,服务器最终以超时响应。
So my question is - why does it behave this way? It seems wrong based on the HTTP spec and other browsers don't behave this way. Is it simply a bug? Surely this creates havoc in any serious AJAX based Web application.
所以我的问题是 - 为什么它会这样?根据 HTTP 规范,这似乎是错误的,而其他浏览器不会以这种方式运行。这只是一个错误吗?这无疑会对任何基于 AJAX 的 Web 应用程序造成严重破坏。
Reference information:
参考信息:
There is a similar problem, triggered by HTTP keep-alive timeouts that are shorter than 1 minute and is documented here:
有一个类似的问题,由短于 1 分钟的 HTTP 保持活动超时触发,并记录在此处:
采纳答案by Dodgyrabbit
There does not seem to be a clear answer to this question, so I will provide my empirical data as a substitute and provide some ways to work around it. Maybe some MS insider will one day shed some light on this...
这个问题似乎没有明确的答案,所以我将提供我的经验数据作为替代,并提供一些解决方法。也许有一天某些 MS 内部人士会对此有所了解...
If HTTP Keep-Alive is disabledon the server, this issue goes away. In other words, your HTTP 1.1 server will respond to every Ajax request with a
Connection: Close
line in the response. This keeps IE happy but causes every Ajax request to open a new connection. This can have a significant performance impact, especially on high latency networks.The issue is triggered easily if Ajax requests are made in rapid succession. For example, we make Ajax requests every 100ms and then the network status changes, the error is easy to reproduce. Although most applications probably do not make such requests, you might well have a couple of server calls happening right after each other which could lead to this problem. Less chatty keeps IE happy.
It happens even without NTLM authentication.
It happens when your HTTP keep-alive timeout on the server is shorter than the default (which defaults to 60 seconds on Windows). Details provided in link in question.
It does not happen with Chrome or Firefox. FF sends one packet so seems to avoid this issue altogether.
It happens in IE 6, 7, 8. Could not reproduce with IE 9 beta.
如果服务器上禁用了HTTP Keep-Alive ,则此问题将消失。换句话说,您的 HTTP 1.1 服务器将在响应中使用
Connection: Close
一行来响应每个 Ajax 请求。这让 IE 满意,但会导致每个 Ajax 请求打开一个新连接。这会对性能产生重大影响,尤其是在高延迟网络上。如果快速连续发出 Ajax 请求,则很容易触发该问题。比如我们每100ms发出一次Ajax请求,然后网络状态发生变化,错误很容易重现。尽管大多数应用程序可能不会发出此类请求,但您很可能会接连发生几个服务器调用,这可能会导致此问题。少说话让 IE 开心。
即使没有 NTLM 身份验证,它也会发生。
当您在服务器上的 HTTP 保持活动超时比默认值(在 Windows 上默认为 60 秒)短时,就会发生这种情况。相关链接中提供的详细信息。
Chrome 或 Firefox 不会发生这种情况。FF 发送一个数据包,因此似乎完全避免了这个问题。
它发生在 IE 6、7、8 中。无法在 IE 9 测试版中重现。
回答by Julian
The microsoft KB article titled When you use Microsoft Internet Explorer or another program to perform a re-POST operation, only the header data is postedseems to fix this problem.
题为“当您使用 Microsoft Internet Explorer 或其他程序执行重新 POST 操作时,仅发布标头数据”的 microsoft KB 文章似乎可以解决此问题。
The article provides a hotfix. For later browsers such as IE8 it says the hotfix is already included but needs to be enabledthrough the registry settings on the client PC.
文章提供了一个修补程序。对于 IE8 等更高版本的浏览器,它表示已包含此修补程序,但需要通过客户端 PC 上的注册表设置启用。
回答by reassembler
I had a similar problem where some older versions of IE would send back only the Header and not the body of a POST. My problem turned out to be related to IE and NTLM. Since you didn't mention NTLM, this probably does not help, but just in case:
我有一个类似的问题,一些旧版本的 IE 只会发回 Header 而不是 POST 的正文。我的问题原来与 IE 和 NTLM 有关。由于您没有提到 NTLM,这可能无济于事,但以防万一:
回答by The-MeLLeR
Are you using NTLM authentication?
您是否使用 NTLM 身份验证?
When using NTLM authentication, IE doesn't send post-data. It sends header info, expects an unauthorized response send authorization, and after the 're-authentication' sends the post.
使用 NTLM 身份验证时,IE 不发送后数据。它发送标头信息,期望未经授权的响应发送授权,并在“重新认证”后发送帖子。
回答by barrycarter
This is a longshot, but IE (and even Firefox) sometimes "remembers" the connection it uses for an HTTP request. Notes/examples:
这是一个远景,但 IE(甚至 Firefox)有时会“记住”它用于 HTTP 请求的连接。注释/示例:
In Firefox, if I change the proxy settings and hit SHIFT-RELOAD on a page, it still uses the old proxy. However, if I kill the old proxy ("killall squid"), it starts using the new proxy.
When you disconnect/reconnect, do you receive a new IP address or anything similar? Can you somehow monitor the old IP address to see if IE is sending data to that now-dead address?
My guess is that IE is sending the data, just down the wrong path. It might be smart enough to not cache network connections for "POST" packets, but might not be smart enough to do that for POST payloads.
This probably doesn't affect most AJAX apps, since people rarely disconnect and re-connect to their networks?
在 Firefox 中,如果我更改代理设置并在页面上点击 SHIFT-RELOAD,它仍然使用旧代理。但是,如果我杀死旧代理(“killall squid”),它将开始使用新代理。
当您断开/重新连接时,您是否收到新的 IP 地址或类似的地址?您能否以某种方式监视旧 IP 地址以查看 IE 是否正在将数据发送到那个现已失效的地址?
我的猜测是 IE 正在发送数据,只是走错了路。它可能足够聪明,不会为“POST”数据包缓存网络连接,但可能不够聪明,无法为 POST 有效负载执行此操作。
这可能不会影响大多数 AJAX 应用程序,因为人们很少断开连接并重新连接到他们的网络?
回答by robbie kouwenberg
I had a similar problem today when using $.ajax and was able to fix it by setting async to false.
我今天在使用 $.ajax 时遇到了类似的问题,并且能够通过将 async 设置为 false 来修复它。
$.ajax({
async: false,
url: '[post action url]',
data: $form.serialize(),
type: 'POST',
success: successCallback
});