中止/取消/放弃角度js中的http请求并再次重试

时间:2017-05-24 12:57:06

标签: angularjs http xmlhttprequest interceptor abort

我正在开发一个应用程序,如果某段时间过去,我必须停止收听请求,如果在60秒内没有来自请求的响应,那么我必须中止该请求,并且一次有多个请求。我不知道如何用中止时间(60秒)跟踪每个请求。我的意思是我怎么知道哪个请求会中止。

我想在 AngularJS 拦截器中实现此功能。我已经尝试了很多博客并发布声称实现此功能的声明,但没有任何帮助我

这是我的拦截器代码

    $httpProvider.interceptors.push(['$cookies', '$rootScope', '$q', '$localStorage', '$sessionStorage','$timeout', function ($cookies, $rootScope, $q, $localStorage, $sessionStorage, $timeout) {
        return {
            'request': function (config) {
                config.headers = config.headers || {};
                if (typeof config.data !== 'object') {
                    config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
                }
                config.headers.Accept = 'application/json;odata=verbose';
                config.headers['X-Requested-With'] = 'XMLHttpRequest';
                var token = $localStorage.authToken || $sessionStorage.authToken;                    
                if (token) {
                    config.headers.Authorization = 'Bearer ' + token;
                }

                return config;
            },
            'responseError': function (response) {
                var status = response.status;
                var error = '';
                if(response.data.error) {
                    error = response.data.error;
                }
                if(status === 401) {
                    $rootScope.unauthorizedLogout();
                } else if(status === 400 && (error === 'token_invalid' || error === 'token_not_provided')) {
                    $rootScope.unauthorizedLogout();
                } 
                return $q.reject(response);
            }
        };
    }]); 

我尝试了$q.defer并且它是取消请求的解决方法,但它并没有帮助我在应用程序中实现我想要的功能。

和平 V

2 个答案:

答案 0 :(得分:0)

您可以尝试使用全局超时设置所有请求 $ httpProvider.defaults.timeout;

angular.module('test', [])
  .config(['$httpProvider', function($httpProvider) {
    $httpProvider.defaults.timeout = 60000;
}]);

答案 1 :(得分:0)

This answer helped me a lot

设置递增的超时值以请求

    config.timeout = incrementalTimeout;

处理响应错误的拦截器应如下所示

   'responseError': function (response) {
    var status = response.status;
    var error = '';
    //functionality to for request aborting and resending
    if (status === -1 || status >= 500) {
        if (attempts <= 3) {
            attempts += 1;
            return retryRequest(response.config);
        }
    } else {
        // set incrementalTiemout and attempts to default value   
        incrementalTimeout = 4000;
        attempts = 1;
    }
    if(response.data.error) {
        error = response.data.error;
    }
    if(status === 401) {
        $rootScope.unauthorizedLogout();
    } else if(status === 400 && (error === 'token_invalid' || error === 'token_not_provided')) {
        $rootScope.unauthorizedLogout();
    }
    return $q.reject(response);
}

在拦截器中重新发送请求的代码

        // default request timeout is of 4 seconds and attempt is 1
        var incrementalTimeout = 4000;
        var attempts = 1;
        function retryRequest (httpConfig) {
            var thisTimeout = incrementalTimeout;
            incrementalTimeout += 1000;
            return $timeout(function() {
                var $http = $injector.get('$http');
                return $http(httpConfig);
            }, thisTimeout);
        }