복붙노트

[JQUERY] jQuery를 사용하여 실패에 AJAX 요청을 다시 시도하는 가장 좋은 방법은 무엇입니까?

JQUERY

jQuery를 사용하여 실패에 AJAX 요청을 다시 시도하는 가장 좋은 방법은 무엇입니까?

해결법


  1. 1.이 같은:

    이 같은:

    
    $.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
            }
        }
    });
    

  2. 2.

    (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);
    
    // define ajax settings
    var 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 deferred
    function onFail(){
      if( ajaxSettings.retries-- > 0 )
        setTimeout(function(){
            $.ajax(ajaxSettings).fail(onFail);
        }, 1000);
    }
    
    // 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') 
    });
    

    고려해야 할 점은 반드시 $ 아약스 방법은 이미 두 번 실행되는 동일한 코드를 방지하기 위해, 이전에 포장되지 않은하고있다.

    당신은 복사하여 붙여 넣을 수 있습니다 이러한 조각을 (그대로)을 테스트 할 수있는 콘솔


  3. 3.나는 아래의 코드와 성공을 많이 했어 (예 : http://jsfiddle.net/uZSFK/)

    나는 아래의 코드와 성공을 많이 했어 (예 : 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 );
            });
    }
    

  4. 4.나중에 전화 뒷면에 부착 성공 방법을 가지고 있지 않기 때문에 누군가의 전화가 아약스 호출 후 ()되는 .done 경우 이러한 답변 없음이 작동하지 않습니다. 그래서 사람이 않는 경우 :

    나중에 전화 뒷면에 부착 성공 방법을 가지고 있지 않기 때문에 누군가의 전화가 아약스 호출 후 ()되는 .done 경우 이러한 답변 없음이 작동하지 않습니다. 그래서 사람이 않는 경우 :

    $.ajax({...someoptions...}).done(mySuccessFunc);
    

    그런 다음 mySuccessFunc은 재시도 호출되지 않습니다. 여기에 크게 여기 @의 cjpak의 대답에서 차용 내 솔루션입니다. 내 경우에는 내가 502 오류 때 AWS의 API 게이트웨이 응답을 다시 시도합니다.

    const RETRY_WAIT = [10 * 1000, 5 * 1000, 2 * 1000];
    
    // This is what tells JQuery to retry $.ajax requests
    // Ideas for this borrowed from https://stackoverflow.com/a/12446363/491553
    $.ajaxPrefilter(function(opts, originalOpts, jqXHR) {
      if(opts.retryCount === undefined) {
        opts.retryCount = 3;
      }
    
      // Our own deferred object to handle done/fail callbacks
      let dfd = $.Deferred();
    
      // If the request works, return normally
      jqXHR.done(dfd.resolve);
    
      // If the request fails, retry a few times, yet still resolve
      jqXHR.fail((xhr, textStatus, errorThrown) => {
        console.log("Caught error: " + JSON.stringify(xhr) + ", textStatus: " + textStatus + ", errorThrown: " + errorThrown);
        if (xhr && xhr.readyState === 0 && xhr.status === 0 && xhr.statusText === "error") {
          // API Gateway gave up.  Let's retry.
          if (opts.retryCount-- > 0) {
            let retryWait = RETRY_WAIT[opts.retryCount];
            console.log("Retrying after waiting " + retryWait + " ms...");
            setTimeout(() => {
              // Retry with a copied originalOpts with retryCount.
              let newOpts = $.extend({}, originalOpts, {
                retryCount: opts.retryCount
              });
              $.ajax(newOpts).done(dfd.resolve);
            }, retryWait);
          } else {
            alert("Cannot reach the server.  Please check your internet connection and then try again.");
          }
        } else {
          defaultFailFunction(xhr, textStatus, errorThrown); // or you could call dfd.reject if your users call $.ajax().fail()
        }
      });
    
      // NOW override the jqXHR's promise functions with our deferred
      return dfd.promise(jqXHR);
    });
    

    이 조각은, 다음 2 초 후에 다음 5 초 10 초 오프 백업하고 다시 시도 할 당신이 수있는 RETRY_WAIT 일정을 수정하여 편집.

    AWS 지원은 파란색 달에 한 번 우리를 위해 일하기 때문에 우리가 재 시도를 추가 제안했다.


  5. 5.다음은이을위한 작은 플러그인은 다음과 같습니다

    다음은이을위한 작은 플러그인은 다음과 같습니다

    https://github.com/execjosh/jquery-ajax-retry

    자동 증가 제한 시간은에 좋은 추가 될 것이다.

    이 전 세계적으로 단지 $ 아약스 서명으로 자신의 함수를 작성가 재시도 API를 사용하여 새로운 기능에 의해 모든 $ 아약스 전화를 대체 사용합니다.

    또한 직접 $ 아약스를 대체 할 수 있지만 다음 재시도없이 XHR 호출을 할 수 없습니다.


  6. 6.여기에 라이브러리의 비동기 로딩 나를 위해 일한 방법이다 :

    여기에 라이브러리의 비동기 로딩 나를 위해 일한 방법이다 :

    var jqOnError = function(xhr, textStatus, errorThrown ) {
        if (typeof this.tryCount !== "number") {
          this.tryCount = 1;
        }
        if (textStatus === 'timeout') {
          if (this.tryCount < 3) {  /* hardcoded number */
            this.tryCount++;
            //try again
            $.ajax(this);
            return;
          }
          return;
        }
        if (xhr.status === 500) {
            //handle error
        } else {
            //handle error
        }
    };
    
    jQuery.loadScript = function (name, url, callback) {
      if(jQuery[name]){
        callback;
      } else {
        jQuery.ajax({
          name: name,
          url: url,
          dataType: 'script',
          success: callback,
          async: true,
          timeout: 5000, /* hardcoded number (5 sec) */
          error : jqOnError
        });
      }
    }
    

    그런 다음 당신의 응용 프로그램과 둥지 성공 콜백에서 .load_script 전화 :

    $.loadScript('maps', '//maps.google.com/maps/api/js?v=3.23&libraries=geometry&libraries=places&language=&hl=&region=', function(){
        initialize_map();
        loadListeners();
    });
    

  7. 7.오류 기능이 있기 때문에, Zepto 작동하지 않습니다 DemoUsers의 대답은 윈도우를 가리키고 있습니다. (그리고 '이'사용의 방법은 그들이 아약스 또는 필요를 구현하는 방법을 알고하지 않는 보안 충분하지 않습니다.)

    오류 기능이 있기 때문에, Zepto 작동하지 않습니다 DemoUsers의 대답은 윈도우를 가리키고 있습니다. (그리고 '이'사용의 방법은 그들이 아약스 또는 필요를 구현하는 방법을 알고하지 않는 보안 충분하지 않습니다.)

    지금은 나를 위해 잘 작동까지 Zepto를 들어, 어쩌면 당신은, 아래 시도 할 수 있습니다 :

    var AjaxRetry = function(retryLimit) {
      this.retryLimit = typeof retryLimit === 'number' ? retryLimit : 0;
      this.tryCount = 0;
      this.params = null;
    };
    AjaxRetry.prototype.request = function(params, errorCallback) {
      this.tryCount = 0;
      var self = this;
      params.error = function(xhr, textStatus, error) {
        if (textStatus === 'timeout') {
          self.tryCount ++;
          if (self.tryCount <= self.retryLimit) {
            $.ajax(self.params)      
            return;
          }
        }
        errorCallback && errorCallback(xhr, textStatus, error);
      };
      this.params = params;
      $.ajax(this.params);
    };
    //send an ajax request
    new AjaxRetry(2).request(params, function(){});
    

    사용 생성자는 확인 요청에 재진입 할 ​​수 있습니다!


  8. 8.코드는 거의 꽉 :)

    코드는 거의 꽉 :)

    const counter = 0;
    $(document).ajaxSuccess(function ( event, xhr, settings ) {
        counter = 0;
    }).ajaxError(function ( event, jqxhr, settings, thrownError ) {
        if (counter === 0 /*any thing else you want to check ie && jqxhr.status === 401*/) {
            ++counter;
            $.ajax(settings);
        }
    });
    
  9. from https://stackoverflow.com/questions/10024469/whats-the-best-way-to-retry-an-ajax-request-on-failure-using-jquery by cc-by-sa and MIT license