ChatGPT解决这个技术问题 Extra ChatGPT

Why does Internet Explorer not send HTTP post body on Ajax call after failure?

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

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.

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.

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.

Reference information:

There is a similar problem, triggered by HTTP keep-alive timeouts that are shorter than 1 minute and is documented here:

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

This is an excellent, well-defined question that deserves an answer. Unfortunately, this is a little off topic. I'm not sure if it would be better on webmasters.stackexchange.com or superuser.stackexchange.com.
@gilly3, I think something must be wrong with me, because I read that and was just nodding along...
@gilly3: when translated to Dutch this would be correct, as 'googelen' is a verb (even defined in the Dutch dictionary) meaning 'to search the web' in Dutch. Yes, it's spelled 'googelen' and not 'googlen'. Odd, I know. So, you could just say: 'Googel dit probleem met Bing.' and it'd be correct.
@gilly3: What's Bing? I'm gonna Google it.
"why does it behave this way?" -- would you accept for an answer "Microsoft people, though for the most part brilliant, are part of a programming culture fundamentally different from those of us who came into the digital age through DEC, Unix, Apple, Commodore, or other backgrounds, and tend to do things which makes the rest of us gasp in wonder, not at their brilliance, but at their overcomplication and total corruption of things that are simple and straightforward to the rest of us"?

C
Chepech

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...

If HTTP Keep-Alive is disabled on 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.


Are there other ways to fix this problem? Any javascript fix? I tried looking at the various XMLHTTP objects and they still didn't fix the issue.
J
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 posted seems to fix this problem.

The article provides a hotfix. For later browsers such as IE8 it says the hotfix is already included but needs to be enabled through the registry settings on the client PC.


I am experiencing this problem with IE10, which the article doesn't mention.
The article now mentions up to IE11, so it looks like this was never fixed.
I believe I am experiencing this issue on a production site - the user agents associated with the issue correspond with IE 8,9,10 and 11.
Has anyone found a workaround? Specifically I send a 307 and FF, Chrome, Safari repost the data to the new endpoint - IE does not. I can't ask my users to hotfix / registry patch.
r
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:

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


Your link was helpful in solving similar problem in IE 11 and IIS 6.
佚名

This is a longshot, but IE (and even Firefox) sometimes "remembers" the connection it uses for an HTTP request. Notes/examples:

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?


I think the problem is the last one. I think Microsoft uses a "rarely happens: don't implement"-policy. :)
I monitor all HTTP traffic from source to destination. I can confirm that (a) my IP address did not change and (b) there is no attempt to send anything else. IE opens a new socket and sends a partial request. The way I read the MS article, is one of their security updates broke IE. Then they created a patch to fix that. But just in case you wanted it to behave the old "broken" way, you could add this registry key. Retry_HeaderOnlyPOST_OnConnectionReset. Just trying to make sense of the madness.
On your last point: if you have an Ajax app that polls periodically, say 10 seconds, we find that if left open for a few hours this error will invariably happen. Probably Wifi connection that drops or sketchy network - but our experience this problem is very real.
T
The-MeLLeR

Are you using NTLM authentication?

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.


We do not use NTLM authentication. Happens with anonymous requests.
r
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, url: '[post action url]', data: $form.serialize(), type: 'POST', success: successCallback });