详解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 学习笔记 element属性控制
Jul 23 Javascript
网络图片延迟加载实现代码 超越jquery控件
Mar 27 Javascript
基于jquery ajax 用户无刷新登录方法详解
Apr 28 Javascript
jQuery Ajax提交表单查询获得数据实例代码
Sep 19 Javascript
JavaScript获取当前页面上的指定对象示例代码
Feb 28 Javascript
JQuery+CSS实现图片上放置按钮的方法
May 29 Javascript
jQuery左右滚动支持图片放大缩略图图片轮播代码分享
Aug 26 Javascript
jQuery ajaxSubmit 实现ajax提交表单局部刷新
Jul 04 Javascript
微信小程序 input输入框详解及简单实例
Jan 10 Javascript
jQuery 判断元素整理汇总
Feb 28 Javascript
打造通用的匀速运动框架(实例讲解)
Oct 17 Javascript
vue实现条件判断动态绑定样式的方法
Sep 29 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防注入安全代码
2008/04/09 PHP
php将html转为图片的实现方法
2017/05/19 PHP
php基于自定义函数记录log日志方法
2017/07/21 PHP
php统计数组不同元素的个数的实例方法
2019/09/26 PHP
IE autocomplete internet explorer's autocomplete
2007/06/30 Javascript
JQuery与iframe交互实现代码
2009/12/24 Javascript
html超链接打开窗口大小的方法
2013/03/05 Javascript
主页面中的两个iframe实现鼠标拖动改变其大小
2013/04/16 Javascript
js自动下载文件到本地的实现代码
2013/04/28 Javascript
JQuery中对Select的option项的添加、删除、取值
2013/08/25 Javascript
jquery中$.post()方法的简单实例
2014/02/04 Javascript
js从Cookies里面取值的简单实现
2014/06/30 Javascript
深入理解Ajax的get和post请求
2016/06/02 Javascript
详解js中Number()、parseInt()和parseFloat()的区别
2016/12/20 Javascript
vue.js模仿京东省市区三级联动的选择组件实例代码
2017/11/22 Javascript
轻量级JS Cookie插件js-cookie的使用方法
2018/03/22 Javascript
Angular CLI在Angular项目中如何使用scss详解
2018/04/10 Javascript
3分钟了解vue数据劫持的原理实现
2019/05/01 Javascript
vue 表单输入框不支持focus及blur事件的解决方案
2020/11/17 Vue.js
如何在JavaScript中正确处理变量
2020/12/25 Javascript
[01:34]2014DOTA2 TI预选赛预选赛 选手比赛房大揭秘!
2014/05/20 DOTA
Python批量合并有合并单元格的Excel文件详解
2018/04/05 Python
Python range、enumerate和zip函数用法详解
2019/09/11 Python
python网络爬虫 CrawlSpider使用详解
2019/09/27 Python
Python获取统计自己的qq群成员信息的方法
2019/11/15 Python
Python pickle模块实现对象序列化
2019/11/22 Python
python uuid生成唯一id或str的最简单案例
2021/01/13 Python
Oasis服装官网:时尚女装在线
2020/07/09 全球购物
100%法国制造的游戏和玩具:Les Jouets Français
2021/03/02 全球购物
竞选村长演讲稿
2014/04/28 职场文书
学校领导班子四风问题整改意见
2014/10/02 职场文书
反对四风自我剖析材料
2014/10/07 职场文书
2014年教研室工作总结
2014/12/06 职场文书
2015年暑期社会实践活动总结
2015/03/27 职场文书
认识实习感想
2015/08/10 职场文书
php微信小程序解包过程实例详解
2021/03/31 PHP