以角度发送嵌套的$ http请求

时间:2017-05-17 08:13:05

标签: javascript angularjs

在我的AngularJS 1.6.4 应用程序中,在发送任何$ http请求之前需要进行一些检查,因此我创建了一个服务来处理它并使用它来发送任何请求。此服务仅包含一个公共功能"发送"获取请求的数据并进行一些检查: 1-检查是否有令牌:如果没有发送请求获取访客令牌,则发送所需的请求。 2-如果有令牌:检查它是否已过期:如果没有发送所需的请求。 3-如果已过期:发送刷新令牌请求,然后发送所需的请求。

我的服务代码:

(function() {
  function service($http, tokenManager, apiService, API_URL, REFRESH_TOKEN_URL, appToken) {
    var s = {};
    var defaultToken = appToken;


    s.send = function(data) {
      var token = tokenManager.getToken();
      if (token && token.length > 0) {
        // check if expired
        var isTokenExpired = tokenManager.isTokenExpired();
        if (isTokenExpired) {
          sendRefreshTokenRequest(token).then(function(response) {
            // update the exist token and send with the new one
            return sendTheRequiredRequest(data, token);
          }, function(errors) {

          });
          // token is expired so we need to send refresh token then send our request
        } else {
          // send our request
          return sendTheRequiredRequest(data, token);
        }
      } else {
        token = defaultToken;
        // if the request not login or count send getToken for guest first
        if (data.loginAuthentication || data.countryCitiesAreasList) {
          //send the request with the defaultToken
          return sendTheRequiredRequest(data, defaultToken);
        } else {
          // send guest token first then the request
          sendRequestGetTokenForGuest(defaultToken).then(function(response) {
            var newToken = response.data.token;
            var isSetted = tokenManager.setToken(newToken);
            return sendTheRequiredRequest(data, newToken);
          }, function(errors) {

          });
        }
      }
    };


    function sendRequestGetTokenForGuest(token) {
      var data = apiService.getApiObj("gtoken", "11651");
      var headerParams = createHeaderParams(token);
      return $http({
        method: "POST",
        url: API_URL,
        headers: headerParams,
        data: data 
      });
    }

    function sendRefreshTokenRequest(token) {
      var headerParams = createHeaderParams(token);
      return $http({
        method: "POST",
        url: REFRESH_TOKEN_URL,
        headers: headerParams
      });
    }

    function sendTheRequiredRequest(data, token) {
      var headerParams = createHeaderParams(token);
      return $http({
        method: "POST",
        url: API_URL,
        headers: headerParams,
        data: data
      });
    }

    function createCurrentTimeStamp() {
      return Math.floor(Date.now()).toString();
    }

    function createHeaderParams(token) {
      var headerParams = {
        token: token,
        clientTimeStamp: createCurrentTimeStamp()
      };
      return headerParams;
    }

    return s;
  }
  angular.module('app').factory('apiRequestSender', service);
})();

我通过调用函数" send"在每个控制器的每个服务中使用此服务。并将数据传递给它并返回:

return apiRequestSender.send(data);

然后在路由中使用此服务:

   {
      name: 'home',
      url: '/index',
      templateUrl: 'home/views/index.html',
      controller: 'homeController',
      controllerAs: 'vm',
      resolve: {
        apiResponse: function(homeApiService) {
          return homeApiService.getCitiesAreas();
        }
      }
    }

现在州没有渲染,所以我的错误是什么,或者我在每次请求之前如何实施这些检查?

1 个答案:

答案 0 :(得分:0)

我认为在这里使用$http拦截器会很有用。 See Docs

基本上,这将确保您的功能检查在每个之前执行 请求。这里的要点是request函数接收配置对象,然后你可以 修改&检查此config对象,您需要做的就是确保返回此(或新的)config对象。 (直接或在承诺内返回)

由于您需要在Interceptor中执行一些$http请求,因此您需要确保 它不会以无限循环结束。所以,这里的重点是检查你的URL 在拦截器本身可以做到,当一个请求带有这样的URL时,你就是这样 返回Config对象。

我使用您的代码为您制作了样品工厂

  

请注意,这未经过测试,应该只是让您了解如何操作

myInterceptor.js

angular
  .module('app')
  .factory('myInterceptor', myInterceptor);


myInterceptor.$inject = [
  '$http',
  'tokenManager',
  'apiService',
  'REFRESH_TOKEN_URL',
  'GUEST_TOKEN_URL'
];

function myInterceptor($http, tokenManager, apiService, REFRESH_TOKEN_URL, GUEST_TOKEN_URL) {
  return {
    request: request
  };

  function request(config) {
    if (config.url === REFRESH_TOKEN_URL || config.url === GUEST_TOKEN_URL) {
      // Make sure to avoid an Infinite Loop (http calls within the Interceptor)
      return config;
    }

    var defaultToken = appToken;
    var token = tokenManager.getToken();
    if (token && token.length > 0) {

      var isTokenExpired = tokenManager.isTokenExpired();
      if (isTokenExpired) {

        // Set the Header Params and return the Config object.
        return sendRefreshTokenRequest(token).then(function(response) {
          config.headers = createHeaderParams(token);
          return config;
        });

      } else {

        config.headers = createHeaderParams(token);
        return config;
      }
    } else {
      token = defaultToken;

      if (data.loginAuthentication || data.countryCitiesAreasList) {
        config.headers = createHeaderParams(defaultToken);
        return config;
      } else {
        // Set the Header Params and return the Config object.
        return sendRequestGetTokenForGuest(defaultToken).then(function(response) {
          var newToken = response.data.token;
          var isSetted = tokenManager.setToken(newToken);
          config.headers = createHeaderParams(newToken);
          return config;
        });
      }
    }
  }

  function createCurrentTimeStamp() {
    return Math.floor(Date.now()).toString();
  }

  function createHeaderParams(token) {
    var headerParams = {
      token: token,
      clientTimeStamp: createCurrentTimeStamp()
    };
    return headerParams;
  }

  function sendRequestGetTokenForGuest(token) {
    var data = apiService.getApiObj("gtoken", "11651");
    var headerParams = createHeaderParams(token);
    return $http({
      method: "POST",
      // url: API_URL,
      // Changed because you want to capture this URL in the Interceptor,
      // so it wont do its checks when the url is like this. (avoid Infinite loop)
      url: GUEST_TOKEN_URL,
      headers: headerParams,
      data: data
    });
  }

  function sendRefreshTokenRequest(token) {
    var headerParams = createHeaderParams(token);
    return $http({
      method: "POST",
      url: REFRESH_TOKEN_URL,
      headers: headerParams
    });
  }
}

注册拦截器:

angular
  .module('app')
  .config(['$httpProvider', function($httpProvider) {
    $httpProvider.interceptors.push('myInterceptor');
 }]);

希望这有用:)