循环依赖,同时推动HTTP拦截HTTP

2023-09-13 05:21:26 作者:听风念旧人

我使用HTTP拦截器拦截我的应用程序的每个HTTP请求。但我得到的圆形依赖发现:$ HTTP< - APIInterceptor< - $ HTTP< - $ templateRequest< - $编译

I am using http Interceptor to intercept each http request in my application. But I am getting Circular dependency found: $http <- APIInterceptor <- $http <- $templateRequest <- $compile

这是我的服务code:

here is my Service code:

mPosServices.factory('mosServiceFactory', function ($http, $rootScope, $cookies, $q) {
    return{
         refresh_token: function () {
            var refreshToken = $http({
                method: "get",
                url: "myservice/oauth/token?grant_type=refresh_token&client_id=restapp&client_secret=restapp&refresh_token=" + $cookies.get('refresh_token'),
            })
            return refreshToken;
        }
});

mPosServices.service('APIInterceptor', ['mosServiceFactory','$cookies',function (mosServiceFactory,$cookies) {
        var service = this;
        service.request = function (config) {
            if (!$cookies.get('access_token')) { //if access_token cookie does not exist
               mosServiceFactory.refresh_token().then(function (response) {
                    var date = new Date();
                    date.setTime(date.getTime() + (response.data.expiresIn * 1000));
                    $cookies.remove('access_token');
                    $cookies.put('access_token', response.data.value, {expires: date});
                    $cookies.put('refresh_token', response.data.refreshToken.value);
                }); //call the refresh_token function first
            }
            return config;
        };

        service.responseError = function (response) {
            return response;
        };
    }]);

和推之为:

$httpProvider.interceptors.push('APIInterceptor');

在配置功能。难道我做错了什么吗?即使我试图用手动注入$ HTTP

in config function. Am I doing something wrong here? Even I tried to inject $http manually using

$注射器

,但得到同样的错误。请帮帮我吧。

, but getting same error. Kindly Help me.

推荐答案

您确实需要添加使用 $注射器获得 mosServiceFactory 实例拦截器内。但是,这还不是全部,你需要做的。您还需要确保你不要陷入无限循环的要求,因为拦截器也使得一个请求。你可以做的是检查,如果当前请求是一个令牌刷新,如果是这样不火多了一个要求,我检查这个网址。

You indeed need to add use $injector to get mosServiceFactory instance inside of interceptor. But this is not all you need to do. You also need to make sure you don't fall into infinite request loop because interceptor also makes a request. What you can do is to check if current request is the one for token refresh and if so don't fire one more request, I'm checking the URL for this.

一个更重要的事情提了。你需要从拦截器解析为原始请求配置返回承诺的对象。这样,它担保令牌检索后拦截的请求将被重新发行。

One more important thing to mention. You need to return promise object from interceptor which resolves to original request config. This way it guaranties that intercepted request will be reissued after token is retrieved.

总之看起来是这样的:

mPosServices.service('APIInterceptor', ['$injector', '$cookies', function($injector, $cookies) {
    var service = this;
    service.request = function(config) {
        if (!$cookies.get('access_token') && config.url.indexOf('myservice/oauth/token?grant_type=') === -1) {
            return $injector.get('mosServiceFactory').refresh_token().then(function(response) {
                var date = new Date();
                date.setTime(date.getTime() + (response.data.expiresIn * 1000));
                $cookies.remove('access_token');
                $cookies.put('access_token', response.data.value, {
                    expires: date
                });
                $cookies.put('refresh_token', response.data.refreshToken.value);
            }).then(function() {
                return config; // <-- token is refreshed, reissue original request
            });
        }
        return config;
    };

    service.responseError = function(response) {
        return response;
    };
}]);

检查我的测试解决方案,看看它是如何恢复标记加载后原始请求演示。

Check the demo I was testing solution on to see how it recovers original request after token is loaded.

演示: http://plnkr.co/编辑/ 1Aey2PThZQ4Y8IRZuVOl?p = preVIEW