详解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 相关文章推荐
javascritp实现input输入框相关限制用法
Jun 29 Javascript
js读取本地excel文档数据的代码
Nov 11 Javascript
FusionCharts图表显示双Y轴双(多)曲线
Nov 22 Javascript
Javascript中3种实现继承的方法和代码实例
Aug 12 Javascript
跟我学习javascript的闭包
Nov 16 Javascript
JavaScript中利用jQuery绑定事件的几种方式小结
Mar 06 Javascript
【经典源码收藏】jQuery实用代码片段(筛选,搜索,样式,清除默认值,多选等)
Jun 07 Javascript
微信小程序实现顶部选项卡(swiper)
Jun 19 Javascript
vue的style绑定background-image的方式和其他变量数据的区别详解
Sep 03 Javascript
微信小程序实现语音识别转文字功能及遇到的坑
Aug 02 Javascript
vue仿ios列表左划删除
Sep 26 Javascript
Vue ​v-model相关知识总结
Jan 28 Vue.js
详解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验证码类(分享)
2013/08/06 PHP
又一个PHP实现的冒泡排序算法分享
2014/08/21 PHP
Thinkphp中volist标签mod控制一定记录的换行BUG解决方法
2014/11/04 PHP
PHP 将数组打乱 shuffle函数的用法及简单实例
2016/06/17 PHP
PHP之十六个魔术方法详细介绍
2016/11/01 PHP
浅谈PHP各环境下的伪静态配置
2019/03/13 PHP
javascript实现二分查找法实现代码
2007/11/12 Javascript
jquery下动态显示jqGrid以及jqGrid的属性设置容易出现问题的解决方法
2010/10/22 Javascript
JavaScript 图像动画的小demo
2012/05/23 Javascript
javascript中常用编程知识
2013/04/08 Javascript
extjs ColumnChart设置不同的颜色实现代码
2013/05/17 Javascript
利用jquery.qrcode在页面上生成二维码且支持中文
2014/02/12 Javascript
js离开或刷新页面检测(且兼容FF,IE,Chrome)
2014/03/05 Javascript
javaScript给元素添加多个class的简单实现
2016/07/20 Javascript
jQuery滑动到底部加载下一页数据的实例代码
2017/05/22 jQuery
解决Vue2.0 watch对象属性变化监听不到的问题
2018/09/11 Javascript
详解小程序不同页面之间通讯的解决方案
2018/11/23 Javascript
jQuery点击页面其他部分隐藏下拉菜单功能
2018/11/27 jQuery
js实现删除li标签一行内容
2019/04/16 Javascript
JavaScript检测浏览器是否支持CSS变量代码实例
2020/04/03 Javascript
vue项目前端微信JSAPI与外部H5支付相关实现过程及常见问题
2020/04/14 Javascript
[01:08]DOTA2次级职业联赛 - Wings 战队宣传片
2014/12/01 DOTA
用python读写excel的方法
2014/11/18 Python
python 文件操作api(文件操作函数)
2016/08/28 Python
Python使用POP3和SMTP协议收发邮件的示例代码
2019/04/16 Python
使用Python opencv实现视频与图片的相互转换
2019/07/08 Python
Python中低维数组填充高维数组的实现
2019/12/02 Python
python模块如何查看
2020/06/16 Python
python全栈开发语法总结
2020/11/22 Python
详解CSS3:overflow属性
2020/11/17 HTML / CSS
HTML5声音录制/播放功能的实现代码
2018/05/03 HTML / CSS
Shopping happy life西班牙:以最优惠的价格提供最好的时尚配饰
2020/03/13 全球购物
Unineed中文官网:高端护肤美妆与时尚配饰,英国直邮
2020/07/23 全球购物
2015年度学校卫生工作总结
2015/05/12 职场文书
Mysql Show Profile
2021/04/05 MySQL
Python OpenCV实现图像模板匹配详解
2022/04/07 Python