Angular http拦截器

时间:2015-08-11 11:37:45

标签: angularjs angular-http-interceptors

Angular http拦截器未应用于从拦截器内初始化的请求?

在我们的代码库中,对api的每个请求都有一个以/api/开头的url,我们有一个拦截器,用我们api的实际地址更新这些请求(可以在开发和生产之间轻松切换)一件事的环境)。 更新url后,如果存在访问令牌,拦截器还会添加Authorization标头。这一切都很完美。

但是,有时访问令牌已过期,但我们仍然有刷新令牌,在继续实际请求之前,我首先要向api请求获取新的访问令牌。

因此,在拦截器的request部分,我们调用负责刷新访问令牌的服务,并在该方法返回的then回调中,我们更新原始请求的配置:

//This interceptor only applies to our api calls, do nothing for other requests
if(config.url.substring(0, API_PREFIX.length) !== API_PREFIX) {
    return config;
}

config.url = config.url.replace(API_PREFIX, API_ENDPOINT);

// if we are authenticated, we add the authorization header already
if(AuthSessionService.isAuthenticated()) {
    config.headers['Authorization'] = "Bearer " + AuthSessionService.getAccessToken();
    return config;
}

// so we are not authenticated, but we still do have a refresh-token, this means, we should get a new access-token
if(AuthSessionService.hasRefreshToken()) {
    var deferred = $q.defer(),
        loginService = angular.injector(['MyApp']).get('LoginService');

    loginService.refresh().then(function(result) {
        config.headers['Authorization'] = "Bearer " + AuthSessionService.getAccessToken();
        deferred.resolve(config);
    }).catch(function() {
        deferred.reject('Failed to refresh access token');
    });

    return deferred.promise;
}

//no access-token, no refresh-token, make the call without authorization headers
return config;

但是,登录服务发出的请求似乎没有应用拦截器,因此请求转到/api/login而不是实际的api端点。

这是Angular的设计,当在拦截器的请求方法中发出新的http请求时,没有应用拦截器吗?

1 个答案:

答案 0 :(得分:1)

您的代码流程如下:

0)AngularJS定义$httpProvider;

1)您定义loginService取决于$httpProvider注入$http;

2)你定义一个依赖于loginService的HTTP拦截器并改变$http的工作方式;

3)您定义了注入$http的其他服务。

查看this函数,任何AngularJS提供程序必须提供的$get方法。每次您的服务将$http作为依赖项并returns $http注入时,都会调用它。

现在,如果您返回line 396,则会在调用reversedInterceptors时看到$get列表。它是一个局部变量,因此返回的$http实例将能够使用它,这就是答案reversedInterceptors是每个&的不同参考#34;实例"你注射了$http

因此,注入$http(1)的loginService与注入所有其他服务(3)的reversedInterceptors不同,区别在于它function MyService() { ... } angular.service('MyService', MyService); // which Angular translates to this function MyServiceProvider() { var myService = new MyService(); this.$get = function() { return myService; }; } angular.provider('MyServiceProvider', MyServiceProvider); 尚未包含您在步骤(2)中添加的拦截器。

关于服务与提供商。 服务基于提供者,基本上是这样做的:

function MyOtherProvider() {
    var someStuff = [1, 2, 3];

    this.$get = function() {
        var otherStuff = [5, 6, 7]; // this is how reversedInterceptors is 
                                    // initialized in `$httpProvider`

        function get(url) {
            // do stuff, maybe use otherStuff
        }

        return {
            get: get
        };
    };
}

angular.provider('MyOtherProvider', MyOtherProvider);

虽然提供者是这样的:

MyServiceProvider

Angular仅实例化MyOtherProvider<div id="content"> <div id="videos"> <div id="videos-title-box"> <div id="videos-title-text"></div> </div> <div id="videos-wrapper"> <ul id="videos-ul"> <li class="single-video-li"> <div class="single-video-block"> <a class="img" href="#"> <img class="video-thumb" src="http://tr.nociicon.com/public/upload/fdthum/2014/10/10/face_smile.png"> </a> </div> </li> . . . <li class="single-video-li"> <div class="single-video-block"> <img class="video-thumb" src="http://tr.nociicon.com/public/upload/fdthum/2014/10/10/face_smile.png"> </div> </li> </ul> </div> </div> </div> 一次,但内部发生的事情是不同的。