详解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 相关文章推荐
SlideView 图片滑动(扩展/收缩)展示效果
Aug 01 Javascript
javascript Array对象基础知识小结
Nov 16 Javascript
文本框回车提交与禁止提交示例
Sep 27 Javascript
原生js仿jq判断当前浏览器是否为ie,精确到ie6~8
Aug 30 Javascript
Bootstrap3学习笔记(二)之排版
May 20 Javascript
BootStrap 附加导航组件
Jul 22 Javascript
轻松搞定js表单验证
Oct 13 Javascript
Angular2学习教程之组件中的DOM操作详解
May 28 Javascript
JS字符串去除连续或全部重复字符的实例
Mar 08 Javascript
AngularJS实现的鼠标拖动画矩形框示例【可兼容IE8】
May 17 Javascript
vue2.0 实现富文本编辑器功能
May 26 Javascript
微信小程序实现签字功能
Dec 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
Apache中php.ini的设置方法
2013/02/28 PHP
THINKPHP2.0到3.0有哪些改进之处
2015/01/04 PHP
PHP关联数组实现根据元素值删除元素的方法
2015/06/26 PHP
初识ThinkPHP控制器
2016/04/07 PHP
Laravel框架定时任务2种实现方式示例
2018/12/08 PHP
js自动下载文件到本地的实现代码
2013/04/28 Javascript
js传参数受特殊字符影响错误的解决方法
2013/10/21 Javascript
含有CKEditor的表单如何提交
2014/01/09 Javascript
Node.js环境下Koa2添加travis ci持续集成工具的方法
2017/06/19 Javascript
解决easyui日期时间框ie的兼容的问题
2018/03/01 Javascript
Vue使用json-server进行后端数据模拟功能
2018/04/17 Javascript
Express之托管静态文件的方法
2018/06/01 Javascript
JS二级菜单不同实现方法分析【4种方法】
2018/12/21 Javascript
改进 JavaScript 和 Rust 的互操作性并深入认识 wasm-bindgen 组件
2019/07/13 Javascript
node解析修改nginx配置文件操作实例分析
2019/11/06 Javascript
Bootstrap table 服务器端分页功能实现方法示例
2020/06/01 Javascript
vue 使用lodash实现对象数组深拷贝操作
2020/09/10 Javascript
[51:06]DOTA2-DPC中国联赛 正赛 Elephant vs Aster BO3 第二场 1月26日
2021/03/11 DOTA
Python抓取百度查询结果的方法
2015/07/08 Python
Python程序中用csv模块来操作csv文件的基本使用教程
2016/03/03 Python
Python编写简单的HTML页面合并脚本
2016/07/11 Python
开源软件包和环境管理系统Anaconda的安装使用
2017/09/04 Python
python,Django实现的淘宝客登录功能示例
2019/06/12 Python
Python实现动态给类和对象添加属性和方法操作示例
2020/02/29 Python
Python3 io文本及原始流I/O工具用法详解
2020/03/23 Python
Django实现内容缓存实例方法
2020/06/30 Python
韩国著名的在线综合购物网站:Akmall
2016/08/07 全球购物
国际领先的在线时尚服装和配饰店:DressLily
2019/03/03 全球购物
华为智利官方商店:Huawei Chile
2020/05/09 全球购物
介绍一下木马病毒的种类
2015/07/26 面试题
金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)-> (一千零一拾一元整)输出
2015/05/29 面试题
J2EE的优越性主要表现在哪些方面
2016/03/28 面试题
网上开店必备创业计划书
2014/01/26 职场文书
2014年党的群众路线活动个人整改措施
2014/10/28 职场文书
文明班级申报材料
2014/12/24 职场文书
应届毕业生的自我评价
2019/06/21 职场文书