0

I have a very simple Ajax call, running in a 1 second interval, that updates my page with match status:

var getMatches = function() {
        $.ajax({
            url: '/match',
            type: 'GET',
            success: function(data) {
                avm.matches(data);
            },
            error: function(jqXHR, textStatus, errorThrown) {
                console.log('Error occured: ' + errorThrown);
            }
        });
    };

This worked well from the beginning of the project, but lately started misbehaving - on Chrome only.

The call just won't fire - I have Log::debug on the server side, and the call doesn't reach it. The network panel in Developer Tools does not show a call. The textStatus is 'error', errorThrown is empty, and the jqXHR.status is 0. While this is happening, if I just run http://localhost/match, or even open the same page in FireFox - I get the correct results. So this is NOT a server or routing issue - it's purely in the client.

This behavior started yesterday, and now I'm observing it on the production server as well. And it is sporadic - if I close Chrome, clean cache, etc., it'll work again - for a while. Could there be something in the cache that's blocking the call?

Any ideas how to troubleshoot this?

Traveling Tech Guy
  • 27,194
  • 23
  • 111
  • 159

2 Answers2

5

Sounds like the browser is using the cached response. Try adding the option:

cache: false

to the $.ajax() call.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • If it was using a cached response, why would the textStatus be "error"? – Brad M Jul 23 '13 at 18:07
  • Not sure. But if the network panel doesn't show a call, that seemed like the likely reason. – Barmar Jul 23 '13 at 18:08
  • But the AJAX pending request limit in the other answer now seems like a good guess, too. – Barmar Jul 23 '13 at 18:09
  • I agree with your reasoning, but there exists a glitch in the chrome debugger tool when filtering XHR requests, that some will not show. It's pretty easy to replicate, just filter out xhr, load a page, then click on a different filter, then click back on xhr filter and watch a bunch of new requests magically appear. – Brad M Jul 23 '13 at 18:09
  • @Barmar I added it and it seems to solve my problem. I do see it actively adding a random string to every request. I remember this was an issue years ago, calling the same url repeatedly. But the question is, are there any negative side effects to adding `cache: false`? – Traveling Tech Guy Jul 23 '13 at 18:20
  • @TravelingTechGuy All `cache: false` does is the append to the query string in order to trick the browser into believing that new parameters are being sent and thus the request should not retrieve from cache. – Brad M Jul 23 '13 at 18:24
  • While this answer helps, it appears my first comment in this solution was ignored! It was a rhetorical question....it's impossible that *just* a cached request would cause jQuery to ever trigger the error callback. – Brad M Jul 23 '13 at 18:41
3

I assume you are doing something like this.

setInterval(ajaxFunction, 1000);

What happens if this ajax requests takes more than 1 second to complete? You will have two pending ajax requests. The longer it takes, the more the requests will pile up and eventually cause the browser to go ape-shit.

The solution is to implement something akin to the following.

function ajaxRequest() {
    $.ajax({
         complete: function() {
               setTimeout(ajaxReqest, 1000);
         });
    });
}
Brad M
  • 7,857
  • 1
  • 23
  • 40
  • +1; Most browsers have a fixed number of [maximum simultaneous connections per domain](http://stackoverflow.com/questions/561046/how-many-concurrent-ajax-xmlhttprequest-requests-are-allowed-in-popular-browse). Firefox may have a higher max than Chrome, or it may be faster at resolving your requests to `localhost`. – apsillers Jul 23 '13 at 18:08
  • @Brad I just tried what you suggested, but the problem is: the first call fails - it never reaches the success function to fire the next one.Again, clearing my cache fires it again. – Traveling Tech Guy Jul 23 '13 at 18:14
  • 1
    @TravelingTechGuy The *complete* callback should always be reached, pending no unhandled exceptions. Make sure you include in your response header `"Cache-Control: no-cache"` and set the jQuery ajax setting `cache: false`. The combination of those two settings guarantees (`~99.99%`) the browser will fire the request. – Brad M Jul 23 '13 at 18:16