【问题标题】:AngularJS interceptor retry requestAngularJS 拦截器重试请求
【发布时间】:2015-04-09 23:27:40
【问题描述】:

您好,我正在开发一个 Angular 应用程序,并且在尝试重试在 http 拦截器中发出的最新请求时遇到了一些问题。 我有这个拦截器用于对每个请求进行身份验证验证,并且我在令牌到期的响应中也有它。问题是,当我的令牌过期时,我需要触发刷新令牌以获取新的访问权限,如果成功,则重试拦截的请求。

一切正常。但是...我有多个被拒绝的 401 呼叫,当我尝试登录时(您可以看到 console.log 消息)。似乎只有第一个被拒绝的调用才会触发刷新令牌请求。什么是最好的方法或可以使它起作用的方法?提前 Ty。

var _responseError = function (rejection) {
    if (rejection.status === 401) {
        var authService = $injector.get('authService');
        var state = $injector.get('$state');
        var http = $injector.get('$http');
        var deferred = $q.defer();
        if (rejection.data && rejection.data.ErrorCode == errorCodes.missingRole){
            return $q.reject(rejection);
        }
        //var authData = localStorageService.get(authConstant.cookieName);
        var authData = authService.getAuth();
        if (authData) {
               return authService.refreshToken().then(function (response) {
                       console.log("call is: ", rejection);
                    if (response.access_token){
                        //Todo: find a method to resend last request;
                        return http(rejection.config);
                    }
                },
                function (err) {
                    state.go('app.login');
                    return $q.reject(rejection);
                });
        }
        authService.logOut();
        state.go('app.login');
    }
    return $q.reject(rejection);
};

【问题讨论】:

    标签: javascript angularjs http request interceptor


    【解决方案1】:

    有类似的问题。我的代码有点不一样,但是思路是一样的,试试这个

    var deferred = $q.defer();
    authService.refreshToken().then(function () {
            $http(errorResponse.config).then(deferred.resolve, deferred.reject);
        }, function () {
            authService.logOut().then(deferred.reject);
        });
    
    return deferred.promise;
    

    【讨论】:

    • 非常感谢我终于设法使用请求缓冲区解决了它
    【解决方案2】:

    我已经设法使用 http 缓冲区来存储所有未来被拒绝的后端调用来解决它。 缓冲区代码在这里: https://github.com/witoldsz/angular-http-auth/blob/master/src/http-auth-interceptor.js

    我已经对其进行了一些修改以使其正常工作,这是修改后的版本:

    angular.module('authModule').factory('httpBufferService', ['$injector', function($injector) {
    /** Holds all the requests, so they can be re-requested in future. */
    var buffer = [];
    var doAction=false;
    /** Service initialized later because of circular dependency problem. */
    var $http;
    
    function retryHttpRequest(config, deferred) {
        function successCallback(response) {
            deferred.resolve(response);
        }
        function errorCallback(response) {
            deferred.reject(response);
        }
        $http = $http || $injector.get('$http');
        $http(config).then(successCallback, errorCallback);
    }
    var bufferData = {
        getItems:function (){
            return buffer;
        },
            /**
             * Appends HTTP request configuration object with deferred response attached to buffer.
             */
        append: function(config, deferred) {
            buffer.push({
                config: config,
                deferred: deferred
            });
        },
    
        /**
         * Abandon or reject (if reason provided) all the buffered requests.
         */
        rejectAll: function(reason) {
            if (reason) {
                for (var i = 0; i < buffer.length; ++i) {
                    buffer[i].deferred.reject(reason);
                }
            }
            buffer = [];
        },
        clean:function(){
            buffer = [];
            doAction = false;
        },
        /**
         * Retries all the buffered requests clears the buffer.
         */
        retryAll: function() {
            if (!doAction){
                doAction = true;
                for (var i = 0; i < buffer.length; ++i) {
                    retryHttpRequest(buffer[i].config, buffer[i].deferred);
                }
                bufferData.clean();
            }
    
        }
    };
    return bufferData;
    }]);
    

    这是实现:

    var authData = authService.getAuth();
    httpBuffer.append(rejection.config,defer);
    if (httpBuffer.getItems().length>1){
        return defer.promise;
    }
    if (authData) {
       return authService.refreshToken().then(function (response) {
            if (response.access_token){
                httpBuffer.retryAll();
                return defer.promise;            
            }
        },
        function (err) {        
            httpBuffer.clean();
            authService.logOut();        
            return $q.reject(rejection);
        });
    }
    httpBuffer.clean();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-17
      • 1970-01-01
      • 2014-05-26
      • 2020-02-12
      • 2015-12-11
      • 2016-10-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多