详解为Angular.js内置$http服务添加拦截器的方法

 更新时间:2016年12月20日 09:27:07   作者:SerenoShen  
所谓拦截器就是在目标达到目的地之前对其进行处理以便处理结果更加符合我们的预期。Angular的$http拦截器是通过$httpProvider.interceptors数组定义的一组拦截器,每个拦截器都是实现了某些特定方法的Factory。本文就介绍了为Angular.js内置$http服务添加拦截器的方法。

前言

在Angular框架中,创建团队为使用者进行了Ajax请求的封装,并通过$http服务暴露出相关的接口.Angular在其官方文档中指出, $http服务底层针对Web常见的安全攻击做出了相应的对策,也就是说使用$http服务封装的Ajax为使用者提供了更为安全的保障.作为一个框架,保证框架的可用性,适配性是很有必要的. Angular在设计,实现中也体现出来了这样的良好风格.我们通常在使用Ajax时,有时候希望我们能够在请求发起前或接收到请求后做一些相应的处理工作,比如:在请求发起前,在请求头中添加一下报文段.在请求返回时对一请求处理状态做一些管理,如统一处理404状态等等.Angular的$http服务在设计实现时充分考虑到了上述的情况.接下来,我们一起来学习和了解一下如何为$http服务添加拦截器,以及如何在我们自己实现的服务中实现类似的拦截器机制.

什么是拦截器–What are Interceptors?

Interceptor(拦截器)在服务端框架中属于一种比较常见的机制,如spring,Struts2等Java框架中拦截器属于基本配置项.拦截器提供了一种机制可以使开发者可以定义在一个action(动作)执行的前后执行的代码,这些代码可以是在一个action执行前阻止其执行的代码,也可以是修改目标动作某些行为的代码.(在AOP(Aspect-Oriented Programming)中拦截器用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。在Spring框架中比较常见)

$http服务中的拦截器

查看API或是源码我们可以发现,Angular的实现中通过 httpProvider提供了一个名为interceptors的数组.这个数组接受拦截器服务注册,通过过程次的注册最终会形成拦截器链.这样每次在调用http服务的时候,angular都会通过我们定义的拦截点(切面)进行相应的Ajax动作修改.理论就不多说了,下面开始进入实战:

Angular中如何声明一个拦截器

// Interceptor declaration
module.factory('httpInterceptor', ['$log', function($log) {
  $log.debug('$log is here to show you that this is a regular factory with injection');

  return { 
      // do something
      };
}]);

如何将声明的拦截器注册到$http服务中

// Add the interceptor to $httpProvider.interceptors
module.config(['$httpProvider', function($httpProvider) { 
  $httpProvider.interceptors.push('httpInterceptor');
}]);

通过上面的简单两个步骤,我们基本就完成了http服务的拦截器编写与添加.但是上面的代码片段并不能实际使用,要想真正的实现拦截操作,我们还需要遵循http服务暴露出来的可以进行拦截的点进行相关的代码编写.

$httpProvider暴露了那些可以拦截的点?

  1. request : request方法可以实现拦截请求: 该方法会在 http发送请求到服务器之前执行,因此我们可以在该方法的视线中修改配置或做其他的操作。该方法接收请求配置对象(requestconfigurationobject)作为参数,然后必须返回配置对象或者promise。如果返回无效的配置对象或者promise则会被拒绝,导致http 调用失败。
  2. response : response方法可以实现拦截响应: 该方法会在 http接收到从服务器过来的响应之后执行,因此我们可以修改响应报文或做其他操作。该方法接收响应对象(responseobject)作为参数,然后必须返回响应对象或者promise。响应对象包括了请求配置(requestconfiguration),头(headers),状态(status)和从后台过来的数据(data)。如果返回无效的响应对象或者promise会被拒绝,导致http 调用失败。
  3. requestError : requestError方法可以实现拦截请求异常: 有时候一个请求发送失败或者被拦截器拒绝了。请求异常拦截器会俘获那些被上一个请求拦截器中断的请求。它可以用来恢复请求或者有时可以用来撤销请求之前所做的配置,比如说关闭进度条,激活按钮和输入框什么之类的。
  4. responseError : responseError方法可以实现拦截响应异常: 有时候我们后台调用失败了。也有可能它被一个请求拦截器拒绝了,或者被上一个响应拦截器中断了。在这种情况下,响应异常拦截器可以帮助我们恢复后台调用。

对于上面暴露出来的接口使用也是异常的简单的,我们可以像声明一个简单的服务一样声明一个$http服务的拦截器,并交由angular的注入机制去使用我们配置的拦截器.

// 如同声明一个Angular服务一样声明一个拦截器
module.factory('sessionInjector', ['authService', function (authService){
  return {
    request: function (config){
      if (!authService.isAnonymus) {
        config.headers['x-session-token'] = authService.token;
      }
      return config;
    }
  };
}]);

// 然后将我们声明的拦截器添加到$httpProvider的拦截器链中,之后的服务注入Angular会负责帮我们完善
module.config(['$httpProvider', function ($httpProvider){
  $httpProvider.interceptors.push('sessionInjector');
}]);

$http服务拦截器的异步支持

部分场景下,我们希望在拦截器中能够执行一些异步操作.然后依据不同的处理结果进行不同的拦截操作,AngularJS在设计的时候也很好的支持了这一特性.AngularJS允许我们在拦截的方法中,我们可以返回一个promise对象.如在http服务中,我们如果返回一个promise对象时,http服务将会延迟发起网络请求或是延迟响应请求结果.

module.factory('myInterceptor', ['$q', 'someAsyncService', function($q, someAsyncService) {
  var requestInterceptor = {
    request: function(config) {
      var deferred = $q.defer();
      someAsyncService.doAsyncOperation().then(function() {
        // Asynchronous operation succeeded, modify config accordingly
        ...
        deferred.resolve(config);
      }, function() {
        // Asynchronous operation failed, modify config accordingly
        ...
        deferred.resolve(config);
      });
      return deferred.promise;
    },
    response: function(response) {
          var deferred = $q.defer();
          someAsyncService.doAsyncOperation().then(function() {
            // Asynchronous operation succeeded, modify response accordingly
            ...
            deferred.resolve(response);
          }, function() {
            // Asynchronous operation failed, modify response accordingly
            ...
            deferred.resolve(response);
          });
          return deferred.promise;
        }
  };

  return requestInterceptor;
}]);

上面的例子中,在请求发起时,如果对应的deferred被拒绝,http请求则会失败(如果进行抓包分析的话,你会发现http请求并没有发起).在请求进行响应时,如果deferred被拒绝,则请求也会失败.(抓包分析,网络请求是有返回的).

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

相关文章

  • 实例解析angularjs的filter过滤器

    实例解析angularjs的filter过滤器

    本文对angularjs的filter过滤器进行系统介绍,附上实例解析,便于理解。具有很好的参考价值,需要的朋友可以看下
    2016-12-12
  • AngularJS中$http使用的简单介绍

    AngularJS中$http使用的简单介绍

    在AngularJS中主要使用$http服务与远程http服务器交互,本篇文章主要介绍了AngularJS中$http使用的简单介绍,非常具有实用价值,需要的朋友可以参考下。
    2017-03-03
  • AngularJS安装版本问题解析

    AngularJS安装版本问题解析

    这篇文章主要介绍了AngularJS安装版本问题解析,在这需要注意在安装前请确保自己安装NodeJS环境版本为V18及以上,否则会因node版本问题导致项目无法正常运行,需要的朋友可以参考下
    2024-02-02
  • 详解Angular.js中$http拦截器的介绍及使用

    详解Angular.js中$http拦截器的介绍及使用

    拦截器就是在目标达到目的地之前对其进行处理以便处理结果更加符合我们的预期,下面这篇文章主要给大家介绍了关于Angular.js中$http拦截器的介绍及使用的相关资料,文中介绍的非常详细,需要的朋友可以参考学习。
    2017-07-07
  • AngularJS页面带参跳转及参数解析操作示例

    AngularJS页面带参跳转及参数解析操作示例

    这篇文章主要介绍了AngularJS页面带参跳转及参数解析操作,结合具体实例形式分析了AngularJS使用URL传递参数及参数的接收、解析等相关操作技巧,需要的朋友可以参考下
    2017-06-06
  • angularjs 实现带查找筛选功能的select下拉框实例

    angularjs 实现带查找筛选功能的select下拉框实例

    本篇文章主要介绍了angularjs 实现带查找筛选功能的select下拉框实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-01-01
  • Angular 2.x学习教程之结构指令详解

    Angular 2.x学习教程之结构指令详解

    结构指令通过添加和删除 DOM 元素来更改 DOM 布局。Angular 中两个常见的结构指令是 *ngIf 和 *ngFor,下面这篇文章主要给大家介绍了关于Angular 2.x结构指令的相关资料,需要的朋友可以参考下。
    2017-05-05
  • 深入理解Angularjs向指令传递数据双向绑定机制

    深入理解Angularjs向指令传递数据双向绑定机制

    这篇文章主要深入的给大家介绍了Angularjs向指令传递数据,双向绑定机制的相关资料,需要的朋友可以参考下
    2016-12-12
  • AngularJS表单和输入验证实例

    AngularJS表单和输入验证实例

    本篇文章详细的介绍了AngularJS表单和输入验证实例, AngularJS表单可以提供验证功能。有需要的可以了解一下。
    2016-11-11
  • angular4应用中输入的最小值和最大值的方法

    angular4应用中输入的最小值和最大值的方法

    这篇文章主要介绍了angular4应用中输入的最小值和最大值的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-05-05

最新评论