2013-08-23 4 views
5

Io uso il seguente codice per riprovare le operazioni che restituiscono HTTP 502, 503 o 504:Browser ritorno HTTP 200 con un responseText vuoto

/** 
* @function RetryDelayFunction 
* Returns the amount of time to wait after a failure. 
* 
* @param {Number} retries the number of times the operation has been retried 
* @return {Number} the number of milliseconds to wait before retrying the operation 
*/ 

/** 
* @typedef {Object} RetryAjaxOptions 
* 
* @property {Number} retries the number of times to retry a failed operation 
* @param {RetryDelayFunction} delayFunction maps a failure count to a delay in milliseconds 
* @param {Array} errorCodes the HTTP response codes that should trigger a retry 
*/ 

/** 
* Retries HTTP requests using an exponential back-off in case of HTTP 502, 503, 504. Based on 
* https://github.com/execjosh/jquery-ajax-retry and http://javadoc.google-http-java-client.googlecode.com/hg/1.15.0-rc/com/google/api/client/util/ExponentialBackOff.html 
* 
* The $.ajax() settings object must contain a {@code retry} key to enable this functionality. 
* This object is of type {@link RetryAjaxOptions} and may be used to override the default behavior. 
*/ 
function installAjaxRetries() 
{ 
    "use strict"; 
    /** 
    * Do nothing. 
    */ 
    var noOpFunction = function() 
    { 
    }; 

    var delayInitialIntervalMs = 250; 
    var delayIntervalMultiplier = 1.5; 
    var delayRandomizationFactor = 0.5; 

    /** 
    * @function RetryDelayFunction 
    */ 
    var defaultDelayFunction = function(retries) 
    { 
     var retryInterval = delayInitialIntervalMs * Math.pow(delayIntervalMultiplier, retries); 
     var delta = retryInterval * delayRandomizationFactor; 
     var min = retryInterval - delta; 
     var max = retryInterval + delta; 
     return (Math.random() * (max - min + 1)) + min; 
    }; 

    var MIN_RETRIES = 1; 
    var DEFAULT_RETRIES = 3; 
    var DEFAULT_ERROR_CODES = [502, 503, 504]; 

    var DEFAULT_OPTIONS = 
     { 
      retries: DEFAULT_RETRIES, 
      delayFunction: defaultDelayFunction, 
      errorCodes: DEFAULT_ERROR_CODES 
     }; 
    var originalAjaxFunction = $.ajax; 
    var ajaxWithRetry = function(settings) 
    { 
     settings = $.extend(true, {}, $.ajaxSettings, settings); 
     if (!settings.retry) 
      return originalAjaxFunction(settings); 

     var retries = 0; 
     var options = $.extend(true, {}, $.ajaxRetrySettings, settings.retry); 
     var originalErrorFunction = settings.error || noOpFunction; 
     var originalCompleteFunction = settings.complete || noOpFunction; 

     // Clamp options 
     options.retries = Math.max(MIN_RETRIES, options.retries); 
     options.delayFunction = options.delayFunction || defaultDelayFunction; 

     // Override error function 
     settings.error = function(xhr, textStatus, errorThrown) 
     { 
      if ($.inArray(xhr.status, options.errorCodes) < 0 || retries >= options.retries) 
      { 
       // Give up and call the original error() function 
       originalErrorFunction.call(this, xhr, textStatus, errorThrown); 
       return; 
      } 
      // The complete() handler will retry the operation 
     }; 

     // Override complete function 
     settings.complete = function(xhr, textStatus) 
     { 
      if ($.inArray(xhr.status, options.errorCodes) < 0 || retries >= options.retries) 
      { 
       // Give up and call the original complete() function 
       originalCompleteFunction.call(this, xhr, textStatus); 
       return; 
      } 
      var delayMs = options.delayFunction(retries); 
      ++retries; 
      window.setTimeout(function() 
      { 
       originalAjaxFunction(settings); 
      }, delayMs); 
     }; 

     originalAjaxFunction(settings); 
     return settings.xhr; 
    }; 

    var ajaxRetrySetup = function(options) 
    { 
     DEFAULT_OPTIONS = $.extend(true, DEFAULT_OPTIONS, options); 
     $.ajaxRetrySettings = DEFAULT_OPTIONS; 
     return DEFAULT_OPTIONS; 
    }; 

    $.ajaxRetrySettings = DEFAULT_OPTIONS; 
    $.ajaxRetrySetup = ajaxRetrySetup; 
    $.ajax = ajaxWithRetry; 
} 
installAjaxRetries(); 

Da quando ho iniziato ad usare questo codice, alcune chiamate AJAX ha cominciato ritorno HTTP 200 con una risposta vuota. La cosa strana è che la prima richiesta non va a buon fine (nessun nuovo tentativo è effettivamente in atto) e semplicemente commentando il codice che sovrascrive lo settings.complete risolve il problema. Sto usando Chrome 29.0.1547.57 m.

Perché l'annullamento di settings.complete causa questo problema?

UPDATE: Controllo il server, quindi so per certo che non restituisce mai l'HTTP 200 con una risposta vuota.

UPDATE2: Non riesco più a riprodurre il problema e non ricordo cosa ho fatto per risolverlo. Se non riesco a riprodurlo nei prossimi due mesi, ho intenzione di chiuderlo.

+1

HTTP 200 è la risposta standard per le richieste di successo. Solo una FYI. –

+0

@ jimjimmy1995, capisco ma in questo caso controllo il server e non restituisce mai l'HTTP 200 con una risposta vuota. Questo non è normale :) – Gili

+0

Sia jQuery che la scheda Rete di Chrome mostrano un '200' o solo jQuery? –

risposta

1

può essere che si sta tentando di intestazione di risposta server.set dominio trasversale per consentire accesso origine

+0

Non possibile per due motivi: 1. Invio richieste allo stesso host del file JS (utilizzando percorsi relativi, senza specificare il nome host). 2. In tal caso, commentare "settings.complete" non avrebbe fatto la differenza. Proverò 'allow-access-origin' come hai detto ma non riesco più a riprodurre il problema al momento. – Gili

Problemi correlati