Skip to main content
 首页 » 编程设计

jquery之浏览器返回 HTTP 200 且响应文本为空

2026年07月28日5zhujiabin

我使用以下代码重试返回 HTTP 502、503 或 504 的操作:

/** 
 * @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(); 

自从我开始使用此代码以来,一些 AJAX 调用开始返回带有空响应文本的 HTTP 200。奇怪的是,第一个请求失败(实际上没有重试),只需注释掉覆盖 settings.complete 的代码即可解决问题。我使用的是 Chrome 29.0.1547.57 m。

为什么覆盖 settings.complete 会导致此问题?

更新:我控制服务器,所以我知道它永远不会返回带有空响应的 HTTP 200。

更新2:我无法再重现该问题,并且我不记得我做了什么来解决它。如果我在接下来的几个月内无法重现它,我计划关闭它。

请您参考如下方法:

可能您正在尝试跨域服务器。将响应 header 设置为允许访问来源