2013-08-23 5 views
5

मैं निम्नलिखित कोड का उपयोग आपरेशनों कि वापसी HTTP 502, 503 या 504 पुन: प्रयास करना:एक खाली responseText साथ HTTP 200 लौटने ब्राउज़र

/** 
* @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 ओवरराइड करने वाले कोड को टिप्पणी करने से समस्या ठीक हो जाती है। मैं क्रोम 29.0.1547.57 मीटर का उपयोग कर रहा हूँ।

settings.complete ओवरराइडिंग क्यों इस समस्या का कारण बनता है?

अद्यतन: मैं सर्वर पर नियंत्रण है, इसलिए मुझे पता है कि एक तथ्य के लिए यह एक खाली प्रतिक्रिया के साथ HTTP 200 रिटर्न कभी नहीं।

UPDATE2: अब मैं समस्या को पुन: उत्पन्न नहीं कर सकता और मुझे याद नहीं आया कि मैंने इसे ठीक करने के लिए क्या किया। अगर मैं इसे अगले कुछ महीनों में पुन: पेश नहीं कर सकता हूं तो मैं इसे बंद करने की योजना बना रहा हूं।

+1

HTTP 200 सफल अनुरोधों के लिए मानक प्रतिक्रिया है। बस एक एफवाईआई। –

+0

@ jimjimmy1995, मैं समझता हूं लेकिन इस मामले में मैं सर्वर को नियंत्रित करता हूं और यह खाली प्रतिक्रिया के साथ HTTP 200 कभी नहीं देता है। यह सामान्य नहीं है :) – Gili

+0

क्रोम के jQuery और नेटवर्क टैब दोनों को '200' या केवल jQuery दिखाएं? –

उत्तर

1

हो सकता है आप के लिए अनुमति देने का उपयोग मूल के क्रॉस-डोमेन server.set प्रतिक्रिया हेडर कोशिश कर रहे हैं

+0

दो कारणों से संभव नहीं है: 1. मैं जेएस फ़ाइल के रूप में एक ही होस्ट को अनुरोध भेज रहा हूं (सापेक्ष पथ का उपयोग करके, होस्टनाम निर्दिष्ट नहीं कर रहा हूं)। 2. अगर ऐसा होता है, तो 'settings.complete' पर टिप्पणी करने से कोई फर्क नहीं पड़ता। जैसा कि आपने उल्लेख किया है, मैं 'अनुमति-पहुंच-उत्पत्ति' का प्रयास करूंगा लेकिन अब मैं इस समस्या को पुन: उत्पन्न नहीं कर सकता। – Gili

संबंधित मुद्दे