What's the best way to retry an AJAX request on failure using jQuery? What's the best way to retry an AJAX request on failure using jQuery? ajax ajax

What's the best way to retry an AJAX request on failure using jQuery?


Something like this:

$.ajax({    url : 'someurl',    type : 'POST',    data :  ....,       tryCount : 0,    retryLimit : 3,    success : function(json) {        //do something    },    error : function(xhr, textStatus, errorThrown ) {        if (textStatus == 'timeout') {            this.tryCount++;            if (this.tryCount <= this.retryLimit) {                //try again                $.ajax(this);                return;            }                        return;        }        if (xhr.status == 500) {            //handle error        } else {            //handle error        }    }});


One approach is to use a wrapper function:

(function runAjax(retries, delay){  delay = delay || 1000;  $.ajax({    type        : 'GET',    url         : '',    dataType    : 'json',    contentType : 'application/json'  })  .fail(function(){    console.log(retries); // prrint retry count    retries > 0 && setTimeout(function(){        runAjax(--retries);    },delay);  })})(3, 100);

Another approach would be to use a retries property on the $.ajax

// define ajax settingsvar ajaxSettings = {  type        : 'GET',  url         : '',  dataType    : 'json',  contentType : 'application/json',  retries     : 3  //                 <-----------------------};// run initial ajax$.ajax(ajaxSettings).fail(onFail)// on fail, retry by creating a new Ajax deferredfunction onFail(){  if( ajaxSettings.retries-- > 0 )    setTimeout(function(){        $.ajax(ajaxSettings).fail(onFail);    }, 1000);}

Another way (GIST) - override original $.ajax (better for DRY)

// enhance the original "$.ajax" with a retry mechanism $.ajax = (($oldAjax) => {  // on fail, retry by creating a new Ajax deferred  function check(a,b,c){    var shouldRetry = b != 'success' && b != 'parsererror';    if( shouldRetry && --this.retries > 0 )      setTimeout(() => { $.ajax(this) }, this.retryInterval || 100);  }  return settings => $oldAjax(settings).always(check)})($.ajax);// now we can use the "retries" property if we need to retry on fail$.ajax({    type          : 'GET',    url           : 'http://www.whatever123.gov',    timeout       : 2000,    retries       : 3,     //       <-------- Optional    retryInterval : 2000   //       <-------- Optional})// Problem: "fail" will only be called once, and not for each retry.fail(()=>{  console.log('failed') });

A point to consider is making sure the $.ajax method wasn't already wrapped previously, in order to avoid the same code running twice.


You can copy-paste these snippets (as-is) to the console to test them


I've had a lot of success with this code below (example: http://jsfiddle.net/uZSFK/)

$.ajaxSetup({    timeout: 3000,     retryAfter:7000});function func( param ){    $.ajax( 'http://www.example.com/' )        .success( function() {            console.log( 'Ajax request worked' );        })        .error(function() {            console.log( 'Ajax request failed...' );            setTimeout ( function(){ func( param ) }, $.ajaxSetup().retryAfter );        });}