skip to main | skip to sidebar

Retrying AJAX requests with jQuery ajaxPrefilter
Since jQuery v1.5, it became possible to set timeout on script and JSONP requests. Before that version, timeout was only applied to other types of AJAX requests. Timeout can be very useful as it is the only way to detect the failure of a JSONP request.

When a request timeouts and you need to retry it, here is how to do it using ajaxPrefilter that was introduced in jQuery v1.5. ajaxPrefilter is a callback function that is called before each request is sent to $.ajax() and can be used to handle or modify custom AJAX settings.

In the following snippet, a simple JSONP request is made to get latest tweet from my Twitter timeline.
  • Note that a custom option "retryMax" was set to 2 to retry the request when it timeouts for 2 times maximum.
  • You should consider the worst case when setting the timeout (in milliseconds).
$(document).ready( function(){
   // sample jsonp request to get latest tweet
   $.ajax({
      dataType: 'jsonp'
      ,url: 'https://api.twitter.com/1/statuses/user_timeline.json'
      ,data: { screen_name: 'mike_more', count: 1 }
      ,success: function(json) {
         // display the tweet text on success
         alert( json[0].text );
      }
      ,error: function( jqXHR, textStatus, errorThrown ){
         // display error status on failure
         alert( 'error: ' + textStatus );
      }
      ,timeout:5000
      ,retryMax: 2
   });
});

Now, let's register a prefilter callback. Code should be placed before doing the previous JSONP call -and of course, after including jQuery script!
// register AJAX prefilter : options, original options
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {

   // retry not set or less than 2 : retry not requested
   if( !originalOptions.retryMax || !originalOptions.retryMax >=2 ) return;
   // no timeout was setup
   if( !originalOptions.timeout >0 ) return;

   if( originalOptions.retryCount ) {
      // increment retry count each time
      originalOptions.retryCount++;
   }else{
      // init the retry count if not set
      originalOptions.retryCount = 1;
      // copy original error callback on first time
      originalOptions._error = originalOptions.error;
   };

   // overwrite error handler for current request
   options.error = function( _jqXHR, _textStatus, _errorThrown ){
      // retry max was exhausted or it is not a timeout error
      if( originalOptions.retryCount >= originalOptions.retryMax || _textStatus!='timeout' ){
         // call original error handler if any
         if( originalOptions._error ) originalOptions._error( _jqXHR, _textStatus, _errorThrown );
         return;
      };
      // Call AJAX again with original options
      $.ajax( originalOptions);
   };
});

  • Function checks that retry max and timeout options were set.
  • On the first iteration, it initializes the retry counter and copy the error callback to another option before overriding it.
  • On other iterations, it increments the retry counter.
  • Overrides the error callback for current request to be able to call the AJAX request again when it timeouts.
Have a code suggestion or feedback? let us know in the comments..

1 comments

  1. Shai // July 22, 2012 at 8:33:00 PM GMT+10  

    Very elegant solution, thank you !

Post a Comment

Thank you for taking the time to comment..
* If you have a tech issue with one of my plugins, you may email me on mike[at]moretechtips.net

Mike

Mike MoreWeb developer, jQuery plugin author, social media fan and Technology Blogger.
My favorite topics are: jQuery , Javascript , ASP.Net , Twitter , Google..
<connect with="me"> </connect>

Subscribe by email

Enter your email address:

or via RSS