详解AngularJS中的http拦截


Posted in Javascript onFebruary 09, 2016

http拦截,即$http服务允许我们与服务端交互,有时候我们希望在发出请求之前以及收到响应之后做些事情。
$httpProvider包含了一个interceptors的数组。

我们这样创建一个interceptor。

app.factory('myInterceptor', ['$log', function($log){
  $log.debug('');
  
  var myInterceptor = {};
  
  return myInterceptor;
}])

接着注册interceptor. 

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

以下是$http拦截的一些例子。

■ 拦截器中的异步操作

app.factory('myInterceotpr','someAsyncServcie', function($q, someAsyncServcie){
  var requestInterceptor = {
    request: function(config){
      var deferred = %q.defer();
      someAsyncService.doAsyncOperation().then(function(){
        ...
        deferred.resolve(config);
      }, function(){
        ...
        deferred.resolve(config);
      })
      return deferred.promise;
    }
  };
  
  return requestInterceptor;
})

以上,是一个请求拦截,做了一个异步操作,根据异步操作的结果来更新config。

当然也有响应拦截。

app.factory('myInterceptor',['$q', 'someAsyncService', function($q, someAsyncSercice){
  var responseInterceptor = {
    response: function(response){
      var deferred = $q.defer();
      someAsyncService.doAsyncOperation().then(function(response){
        ...
        deferred.resolve(response);
      }, function(response){
        ...
        deferred.resolve(response);
      })
      return deferred.promise;
    }
  };
  return responseInterceptor;
}])

■ Session拦截,请求拦截

服务端有2种类型的验证,一个是基于cookie的,一种是基于token的。对于基于token验证,当用户登录,获取一个来自服务端的token,这个token在每一次请求时发送给服务端。

创建一个有关session的injector:

app.factory('sessionInjector',['SessionService', function(SessionService){
  var sessionInjector = {
    request: function(config){
      if(!SessionService.isAnonymous){
        config.headers['x-session-token'] = SessionService.token;
      }
      return config;
    }
  };
  
  return sessionInjector;
}])

可见,把从服务端返回的token放在了config.headers中。

注册injector:

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

发出一个请求:

$http.get('');

拦截前大致是:

{
  "transformRequest":[null],
  "transformResponse":[null],
  "method":"GET",
  "url":"",
  "headers":{
    "Accept": "application/json, text/plain,*/*"
  }
}

拦截后,在headers中多两个一个x-session-token字段:

{
  "transformRequest":[null],
  "transformResponse":[null],
  "method":"GET",
  "url":"",
  "headers":{
    "Accept": "application/json, text/plain,*/*",
    "x-session-token":......
  }
}

■ 时间戳,请求和响应拦截

app.factory('timestampMarker',[function(){
  var timestampMarker = {
    request:function(config){
      config.requestTimestamp = new Date().getTime();
      return config;
    },
    response: function(response){
      response.config.responseTimestamp = new Date().getTime();
      return config;
    }
  };
  
  return timestampMarker;
}])

以上,在请求和响应时拦截,在config.requestTimestamp和config.responseTimestamp赋上当前的时间。

注册拦截器:

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

然后在运用的时候可以算出请求响应所耗去的时间。

$http.get('').then(function(response){
  var time = response.config.responseTime - response.config.requestTimestamp;
  console.log('请求耗去的时间为 ' + time);
})

■ 请求错误恢复,请求拦截

模拟一个请求拦截的错误情形:

app.factory('requestRejector',['$q', function($q){
  var requestRejector = {
    request: function(config){
      return $q.reject('requestRejector');
    }
  };
  return requestRejector;
}])

拦截请求错误:

app.factory('requestRecoverer',['$q', function($q){
  var requestRecoverer = {
    requestError: function(rejectReason){
      if(rejectReason === 'requestRejector'){
        //恢复请求
        return {
          transformRequest:[],
          transformResponse:[],
          method:'GET',
          url:'',
          headers:{
            Accept:'application/json, text/plain, */*'
          }
        };
      } else {
        return $q.reject(rejectReason);
      }
    }
  };
  
  return requestRecoverer;
}])

注册拦截器:

app.config(['$httpProvider', function($httpProvider){
  $httpProvider.interceptors.push('requestRejector');
  $httpProvider.interceptors.push('requestRecoverer');
}])

■ Session错误恢复,响应拦截

app.factory('sessionRecoverer',['$q','$injector',function($q, $injector){
 var sessionRecoverer = {
  responseError: function(response){
   //如果Session过期
   if(response.status == 419){
    var SessionService = $injector.get('SessionService');
    var $http = $injector.get('$http');
    var deferred = $q.defer();
    
    //创建一个新的session
    SessionService.login().then(deferred.resolve, deferred.reject);
    
    return deferred.promise.then(function(){
     reutrn $http(response.config);
    })
   }
   return $q.reject(response);
  }
 };
 
 return sessionRecoverer;
}])

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
jQuery Clone Bug解决代码
Dec 22 Javascript
JavaScript地图拖动功能SpryMap的简单实现
Jul 17 Javascript
jquery图片放大功能简单实现
Aug 01 Javascript
javascript内置对象操作详解
Feb 04 Javascript
jQuery绑定事件监听bind和移除事件监听unbind用法实例详解
Jan 19 Javascript
js仿3366小游戏选字游戏
Apr 14 Javascript
深入浅析JavaScript中的arguments对象(强力推荐)
Jun 03 Javascript
js获取指定字符前/后的字符串简单实例
Oct 27 Javascript
Vue2.0父组件与子组件之间的事件发射与接收实例代码
Sep 19 Javascript
jQuery实现获取table中鼠标click点击位置行号与列号的方法
Oct 09 jQuery
如何去除富文本中的html标签及vue、react、微信小程序中的过滤器
Nov 21 Javascript
JS实现transform实现扇子效果
Jan 17 Javascript
详解Javacript和AngularJS中的Promises
Feb 09 #Javascript
深入浅析JavaScript面向对象和原型函数
Feb 06 #Javascript
基于JavaScript实现图片点击弹出窗口而不是保存
Feb 06 #Javascript
javascript+css3 实现动态按钮菜单特效
Feb 06 #Javascript
Angularjs全局变量被作用域监听的正确姿势
Feb 06 #Javascript
JavaScript仿商城实现图片广告轮播实例代码
Feb 06 #Javascript
简介AngularJS中$http服务的用法
Feb 06 #Javascript
You might like
PHP 缓存实现代码及详细注释
2010/05/16 PHP
PHP自带函数给数字或字符串自动补齐位数
2014/07/29 PHP
PHP字符串word末字符实现大小写互换的方法
2014/11/10 PHP
php中array_column函数简单实现方法
2016/07/11 PHP
图文详解PHP环境搭建教程
2016/07/16 PHP
用Jquery实现多级下拉框无刷新的联动
2010/12/22 Javascript
Javascript实现简单二级下拉菜单实例
2014/06/15 Javascript
8个超实用的jQuery功能代码分享
2015/01/08 Javascript
详解Node.js中的事件机制
2016/09/22 Javascript
JavaScript实现百度搜索框效果
2020/03/26 Javascript
Vue的H5页面唤起支付宝支付功能
2019/04/18 Javascript
微信小程序位置授权处理方法
2019/06/13 Javascript
vant中的toast层级改变操作
2020/11/04 Javascript
python实现查找excel里某一列重复数据并且剔除后打印的方法
2015/05/26 Python
用Django实现一个可运行的区块链应用
2018/03/08 Python
Django跨域请求问题的解决方法示例
2018/06/16 Python
python交换两个变量的值方法
2019/01/12 Python
Python使用dict.fromkeys()快速生成一个字典示例
2019/04/24 Python
python取余运算符知识点详解
2019/06/27 Python
详解matplotlib绘图样式(style)初探
2021/02/03 Python
心碎乌托邦的创业计划书范文
2013/12/26 职场文书
工作室成员个人发展规划范文
2014/01/24 职场文书
超市开学活动方案
2014/03/01 职场文书
幼儿园儿童节活动主持词+串词大全
2014/03/21 职场文书
协议书怎么写
2014/04/21 职场文书
工程售后服务承诺书
2014/05/21 职场文书
原料仓仓管员岗位职责
2014/07/08 职场文书
2014年物业管理工作总结
2014/11/21 职场文书
齐云山导游词
2015/02/06 职场文书
餐饮店长岗位职责
2015/04/14 职场文书
用人单位聘用意向书
2015/05/11 职场文书
正规借条模板
2015/05/26 职场文书
感动中国何玥观后感
2015/06/02 职场文书
2016大学生社会实践单位评语
2015/12/01 职场文书
logback 实现给变量指定默认值
2021/08/30 Java/Android
基于Pygame实现简单的贪吃蛇游戏
2021/12/06 Python