używam poniższy kod, żeby ponowić operacje, które zwracają HTTP 502, 503 lub 504:Przeglądarka powrocie HTTP 200 z pustym responseText
/**
* @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();
Odkąd zacząłem używać tego kodu, niektóre rozmowy AJAX zaczęli wracać HTTP 200 z pustym tekstem odpowiedzi. Dziwne jest to, że pierwsze żądanie kończy się niepowodzeniem (w rzeczywistości nie ma miejsca ponowna próba) i po prostu skomentowanie kodu, który przesłania kod settings.complete
, rozwiązuje problem. Używam Chrome 29.0.1547.57 m.
Dlaczego przesłanianie settings.complete
powoduje ten problem?
UPDATE: Kontroluję serwer, więc wiem, że nigdy nie zwraca HTTP 200 z pustą odpowiedzią.
UPDATE2: Nie mogę już odtworzyć problemu i nie pamiętam, co zrobiłem, aby to naprawić. Jeśli nie uda mi się go odtworzyć w ciągu najbliższych kilku miesięcy, planuję go zamknąć.
HTTP 200 jest standardową odpowiedzią na pomyślne żądania. Tylko FYI. –
@ jimjimmy1995, Rozumiem, ale w tym przypadku kontroluję serwer i nigdy nie zwraca HTTP 200 z pustą odpowiedzią. To nie jest normalne :) – Gili
Czy zarówno jQuery, jak i zakładka Network of Chrome wyświetlają "jQuery" lub "200"? –