JQuery Ajax post parameters sometimes not sent on IE

The problem I am having is that when I use jquery ajax post, with very low frequency (< 2%), the post parameters never make it to the server. I do see the post request in the access log. It seems to happen only on IE (I've observed it on 7, 8, and 9 in the logs).

When I switch the call from type "post" to type "get" the issue goes away.

Has anyone else ever seen this odd behavior on IE? Thanks!

I have seen this for various ajax calls, but here is a typical one:

var data= {
    "guess" : "m1",
    "eas" : "hello world"
};

$.ajax({
    url: "http://myco.com/ajaxcall.action",
    data: data,
    type : 'post',
    dataType: 'json',
    success: function(data) {},
    error: function() {}
});

Update: passing "cache: false" does not fix the issue.


Solution 1:

I have spent the last week tracking down a similar problem in my own application (uses Dojo, not JQuery). From your description and frequency of occurrence, I would say it's the same issue.

When HTTP persistent connections are used between browser and server (the default behavior), an HTTP connection can be closed down by the server at any time. This creates a very small timing hole when the browser starts to send a new request at the same time the server closes the connection. Most browsers will use a different connection or open a new connection and resend the request. This is the behavior suggested in RFC 2616 section 8.1.4:


A client, server, or proxy MAY close the transport connection at any time. For example, a client might have started to send a new request at the same time that the server has decided to close the "idle" connection. From the server's point of view, the connection is being closed while it was idle, but from the client's point of view, a request is in progress.

This means that clients, servers, and proxies MUST be able to recover from asynchronous close events. Client software SHOULD reopen the transport connection and retransmit the aborted sequence of requests without user interaction so long as the request sequence is idempotent (see section 9.1.2).


Internet explorer does try to resend the request when this happens, but when it happens to be a POST, it mangles it up by sending the headers (with Content-Length) but no actual data. That is a malformed request and should always lead to an HTTP error (usually after some timeout waiting for the data that never comes).

This bug is documented by Microsoft as KB 895954 (see http://support.microsoft.com/kb/895954). Microsoft first recognized this bug in IE 6. They provided a hotfix, and appear to have shipped the hotfix with every version of IE since then including IE 9. There are two problems with the fix:

  1. The hotfix is not activated by default. You have to create a really weird key using regedit to activate the fix: HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_SKIP_POST_RETRY_ON_INTERNETWRITEFILE_KB895954.

  2. The fix doesn't really fix the problem. The "fixed" behavior is that when the connection is closed when trying to send a request, it does not even try to resend it. It simply passes the error along to the javascript application.

It appears that you have to add error handlers in your code and re-post the request yourself if it fails. I am looking into this solution for my application. My concern is that I'm not sure how to tell if the error I get is caused by a failed attempt to send the query, or some error sent back from the server as a result of the query (in which case I don't want to resend it).

I wrote a C program to simulate a web server and explicitly close a connection to see how the browser handles it. I have found that IE reproduces the errant behavior 100% of the time, while Firefox, Safari and Chrome recover by properly resending the POST on another connection 100% of the time. Perhaps the answer is, "don't use IE."

Solution 2:

As a direct answer to your question: Yes we have just come across this issue and could not find a reasonable explanation. It only affects IE and with a very low frequency - took a long while to get to the conclusion that it is a sporadic jQuery Ajax in IE bug. We had to 'fix' the issue by returning a fail from the server under this condition and re-posting the data after a 1 second delay!

Hacky as hell but seemed to be the only way.

There was definitely no clash with DOM elements etc. and no logical reason for this to happen, the page can be updated many times by the user successfully with intermittent fails.

Must be a bug.

Solution 3:

I think you have to prevent caching in Internet Explorer. Try to set option cache to false.

Example:

$.ajax({
    url: "http://myco.com/ajaxcall.action",
    data: data,
    type : 'post',
    dataType: 'json',
    success: function(data) {},
    error: function() {},
    cache: false
});

Solution 4:

The params sent to the PHP are received from IE in GET:

$.ajax ({
     url: "path/to/ajax.php"
    ,method: "POST"
    ,data: {
         var1: "value1"
        ,var2: true
        ,varX: 123123
    }
    ,cache: false
    ,success: function (data) {
        alert (data);
    }
});

Then on PHP you should use REQUEST instead of POST:

$var1 = $_REQUEST ["var1"]; // value1
$var2 = $_REQUEST ["var2"]; // true
$var3 = $_REQUEST ["var3"]; // 123123

This example could use it for compatibility with IE7