详解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实现类似淘宝购物车全选状态示例
Jun 26 Javascript
JavaScript设计模式之原型模式(Object.create与prototype)介绍
Dec 28 Javascript
javascript的几种继承方法介绍
Mar 22 Javascript
深入浅析knockout源码分析之订阅
Jul 12 Javascript
JS中的hasOwnProperty()和isPrototypeOf()属性实例详解
Aug 11 Javascript
关于Vue Webpack2单元测试示例详解
Aug 14 Javascript
jQuery实现动态控制页面元素的方法分析
Dec 20 jQuery
Vue Router的懒加载路径的解决方法
Jun 21 Javascript
vue项目中添加单元测试的方法
Jul 21 Javascript
JS封装的模仿qq右下角消息弹窗功能示例
Aug 22 Javascript
layui实现数据表格隐藏列的示例
Oct 25 Javascript
通过实例解析jQ Ajax操作相关原理
Sep 23 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/08/08 PHP
解析PHP计算页面执行时间的实现代码
2013/06/18 PHP
php 批量替换程序的具体实现代码
2013/10/04 PHP
php实现获取及设置用户访问页面语言类
2014/09/24 PHP
thinkphp框架实现删除和批量删除
2016/06/29 PHP
脚本吧 - 幻宇工作室用到js,超强推荐share.js
2006/12/23 Javascript
Jquery作者John Resig自己封装的javascript 常用函数
2009/11/09 Javascript
锋利的jQuery 要点归纳(三) jQuery中的事件和动画(上:事件篇)
2010/03/24 Javascript
来自国外的30个基于jquery的Web下拉菜单
2012/06/22 Javascript
加载列表时jquery获取ul中第一个li的属性
2014/11/02 Javascript
手机开发必备技巧:javascript及CSS功能代码分享
2015/05/25 Javascript
jquery实现表单验证简单实例演示
2015/11/23 Javascript
jquery获取文档高度和窗口高度汇总
2016/01/25 Javascript
10个JavaScript中易犯小错误
2016/02/14 Javascript
JS请求servlet功能示例
2017/06/01 Javascript
如何将你的AngularJS1.x应用迁移至React的方法
2018/02/01 Javascript
vue 循环加载数据并获取第一条记录的方法
2018/09/26 Javascript
微信小程序实现的自定义分享功能示例
2019/02/12 Javascript
微信小程序点击顶部导航栏切换样式代码实例
2019/11/12 Javascript
[57:59]EG vs Secret 2018国际邀请赛淘汰赛BO3 第一场 8.22
2018/08/23 DOTA
python使用Queue在多个子进程间交换数据的方法
2015/04/18 Python
Python标准库sched模块使用指南
2017/07/06 Python
Python 将RGB图像转换为Pytho灰度图像的实例
2017/11/14 Python
Python基于贪心算法解决背包问题示例
2017/11/27 Python
python八大排序算法速度实例对比
2017/12/06 Python
在Python 2.7即将停止支持时,我们为你带来了一份python 3.x迁移指南
2018/01/30 Python
python绘制圆柱体的方法
2018/07/02 Python
python 除法保留两位小数点的方法
2018/07/16 Python
Random 在 Python 中的使用方法
2018/08/09 Python
python实现旋转和水平翻转的方法
2018/10/25 Python
Python3实现统计单词表中每个字母出现频率的方法示例
2019/01/28 Python
python flask搭建web应用教程
2019/11/19 Python
在pytorch中实现只让指定变量向后传播梯度
2020/02/29 Python
CSS3 网页下拉菜单代码解释 中文翻译
2010/02/27 HTML / CSS
2014年党员公开承诺书范文
2014/03/28 职场文书
世界无敌的ICOM IC-R9500宽频接收机
2022/03/25 无线电