详解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 简短右键菜单 多浏览器兼容
Jan 01 Javascript
JQuery index()方法使用代码
Jun 02 Javascript
给artDialog 5.02 增加ajax get功能详细介绍
Nov 13 Javascript
基于JQuery 选择器使用说明介绍
Apr 18 Javascript
jquery必须知道的一些常用特效方法及使用示例(整理)
Jun 24 Javascript
javascript工厂方式定义对象
Dec 26 Javascript
JS中捕获console.log()输出的方法
Apr 16 Javascript
快速移动鼠标触发问题及解决方法(ECharts外部调用保存为图片操作及工作流接线mouseenter和mouseleave)
Aug 29 Javascript
vue.js入门教程之计算属性
Sep 01 Javascript
js使用highlight.js高亮你的代码
Aug 18 Javascript
JS库之Three.js 简易入门教程(详解之一)
Sep 13 Javascript
javascript实现拖拽碰撞检测
Mar 12 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
新闻分类录入、显示系统
2006/10/09 PHP
邮箱正则表达式实现代码(针对php)
2013/06/21 PHP
解析PHP函数array_flip()在重复数组元素删除中的作用
2013/06/27 PHP
php+mysql查询实现无限下级分类树输出示例
2016/10/03 PHP
PHP实现十进制、二进制、八进制和十六进制转换相关函数用法分析
2017/04/25 PHP
laravel请求参数校验方法
2019/10/10 PHP
FCK调用方法..
2006/12/21 Javascript
JavaScript中Math对象使用说明
2008/01/16 Javascript
JavaScript 异步调用框架 (Part 3 - 代码实现)
2009/08/04 Javascript
JavaScript 闭包在封装函数时的简单分析
2009/11/28 Javascript
Dreamweaver jQuery智能提示插件,支持版本提示,支持1.6api
2011/07/31 Javascript
JS实现时间格式化的方式汇总
2013/10/16 Javascript
javascript获取URL参数与参数值的示例代码
2013/12/20 Javascript
14款NodeJS Web框架推荐
2014/07/11 NodeJs
简单对比分析JavaScript中的apply,call与this的使用
2015/12/04 Javascript
在AngularJS中使用jQuery的zTree插件的方法
2016/04/21 Javascript
详解ES6中的let命令
2020/04/05 Javascript
判断jQuery是否加载完成,没完成继续判断的解决方法
2017/12/06 jQuery
VueCli3构建TS项目的方法步骤
2018/11/07 Javascript
微信小程序使用蓝牙小插件
2019/09/23 Javascript
利用Python中unittest实现简单的单元测试实例详解
2017/01/09 Python
利用Python将数值型特征进行离散化操作的方法
2018/11/06 Python
Python+Pyqt实现简单GUI电子时钟
2021/02/22 Python
python多进程并发demo实例解析
2019/12/13 Python
python kafka 多线程消费者&手动提交实例
2019/12/21 Python
什么是python的必选参数
2020/06/21 Python
Python关于拓扑排序知识点讲解
2021/01/04 Python
Python中lru_cache的使用和实现详解
2021/01/25 Python
CSS3颜色值RGBA与渐变色使用介绍
2020/03/06 HTML / CSS
英国知名衬衫品牌美国网站:Charles Tyrwhitt美国
2016/08/28 全球购物
业务经理的岗位职责
2013/11/16 职场文书
市场部规章制度
2014/01/24 职场文书
大学生职业生涯规划书参考模板
2014/03/05 职场文书
中秋晚会策划方案
2014/06/12 职场文书
客服专员岗位职责范本
2015/04/07 职场文书
关于做家务的心得体会
2016/01/23 职场文书