详解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 相关文章推荐
Js setInterval与setTimeout(定时执行与循环执行)的代码(可以传入参数)
Jun 11 Javascript
关于JavaScript对象的动态选择及遍历对象
Mar 10 Javascript
js实现的类似于asp数据字典的数据类型代码实例
Sep 03 Javascript
浅谈javascript中this在事件中的应用
Feb 15 Javascript
javascript中SetInterval与setTimeout的定时器用法
Aug 24 Javascript
悬浮广告方法日常收集整理
Mar 18 Javascript
Bootstrap 布局组件(全)
Jul 18 Javascript
Bootstrap树形菜单插件TreeView.js使用方法详解
Nov 01 Javascript
jQuery内容筛选选择器实例代码
Feb 06 Javascript
解决LayUI表单获取不到data的问题
Aug 20 Javascript
用jQuery将JavaScript对象转换为querystring查询字符串的方法
Nov 12 jQuery
react结合bootstrap实现评论功能
May 30 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 addslashes 利用递归实现使用反斜线引用字符串
2013/08/05 PHP
PHP面向对象程序设计OOP继承用法入门示例
2016/12/27 PHP
浅谈PHP的$_SERVER[SERVER_NAME]
2017/02/04 PHP
由document.body和document.documentElement想到的
2009/04/13 Javascript
Jquery 表格合并的问题分享
2011/09/17 Javascript
常用js字符串判断方法整理
2013/10/18 Javascript
javascript调试过程中找不到哪里出错的可能原因
2013/12/16 Javascript
JavaScript中实现PHP的打乱数组函数shuffle实例
2014/10/11 Javascript
纯javascript响应式树形菜单效果
2015/11/10 Javascript
javascript小数精度丢失的完美解决方法
2016/05/31 Javascript
BootstrapTable+KnockoutJS自定义T4模板快速生成增删改查页面
2016/08/01 Javascript
vue开发心得和技巧分享
2016/10/27 Javascript
深入理解Javascript中的valueOf与toString
2017/01/04 Javascript
原生js实现节日时间倒计时功能
2017/01/18 Javascript
vue2 如何实现div contenteditable=“true”(类似于v-model)的效果
2017/02/08 Javascript
javascript浏览器用户代理检测脚本实现方法
2017/10/27 Javascript
微信小程序实现animation动画
2018/01/26 Javascript
vue构建动态表单的方法示例
2018/09/22 Javascript
vue cli3.0 引入eslint 结合vscode使用
2019/05/27 Javascript
js回溯法计算最佳旅行线路代码实例
2019/09/11 Javascript
python 2.6.6升级到python 2.7.x版本的方法
2016/10/09 Python
Python机器学习logistic回归代码解析
2018/01/17 Python
使用tensorflow实现线性svm
2018/09/07 Python
python面向对象实现名片管理系统文件版
2019/04/26 Python
python数据类型之间怎么转换技巧分享
2019/08/20 Python
python3.6中anaconda安装sklearn踩坑实录
2020/07/28 Python
HTML5印章绘制电子签章图片(中文英文椭圆章、中文英文椭圆印章)
2019/06/03 HTML / CSS
英国行业制服供应商:Alexandra
2019/09/14 全球购物
中专自我鉴定范文
2013/10/16 职场文书
2014年秋季新学期寄语
2014/08/02 职场文书
学习与创新自我评价
2015/03/09 职场文书
父亲去世追悼词
2015/06/23 职场文书
小型婚礼主持词
2015/06/30 职场文书
详解Vue router路由
2021/11/20 Vue.js
基于Pygame实现简单的贪吃蛇游戏
2021/12/06 Python
MySQL中B树索引和B+树索引的区别详解
2022/03/03 MySQL