详解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获取后台Cookies值的小例子
Mar 04 Javascript
jquery简单实现鼠标经过导航条改变背景图
Dec 17 Javascript
详谈JavaScript内存泄漏
Nov 14 Javascript
node.js中的fs.fsyncSync方法使用说明
Dec 15 Javascript
详解JavaScript对W3C DOM模版的支持情况
Jun 16 Javascript
AngularJS手动表单验证
Feb 01 Javascript
浅谈js中对象的使用
Aug 11 Javascript
JS获取字符串实际长度(包含汉字)的简单方法
Aug 11 Javascript
vue实现微信分享朋友圈,发送朋友的示例讲解
Feb 10 Javascript
JS Thunk 函数的含义和用法实例总结
Apr 08 Javascript
ant design vue嵌套表格及表格内部编辑的用法说明
Oct 28 Javascript
vue添加自定义右键菜单的完整实例
Dec 08 Vue.js
详解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
现磨咖啡骗局!现磨咖啡=新鲜咖啡?现磨咖啡背后的猫腻你不懂!
2019/03/28 冲泡冲煮
php 引用(&)详解
2009/11/20 PHP
PHP显示今天、今月、上月、今年的起点/终点时间戳的代码
2011/05/25 PHP
php连接mssql数据库的几种方法
2013/02/21 PHP
PHP+Mysql树型结构(无限分类)数据库设计的2种方式实例
2014/07/15 PHP
CI框架AR数据库操作常用函数总结
2016/11/21 PHP
PHP批量删除jQuery操作
2017/07/23 PHP
php 替换文章中的图片路径,下载图片到本地服务器的方法
2018/02/06 PHP
Jquery封装tab自动切换效果的具体实现
2013/07/13 Javascript
jQuery防止click双击多次提交及传递动态函数或多参数
2014/04/02 Javascript
JavaScript避免内存泄露及内存管理技巧
2014/09/05 Javascript
javascript将数字转换整数金额大写的方法
2015/01/27 Javascript
ReactNative实现Toast的示例
2017/12/31 Javascript
jQuery+Cookie实现切换皮肤功能【附源码下载】
2018/03/25 jQuery
Vue项目分环境打包的实现步骤
2018/04/02 Javascript
vuex的module模块用法示例
2018/11/12 Javascript
swiper4实现移动端导航切换
2020/10/16 Javascript
vue-cli4.x创建企业级项目的方法步骤
2020/06/18 Javascript
Python实现单词拼写检查
2015/04/25 Python
开源Web应用框架Django图文教程
2017/03/09 Python
利用Python将每日一句定时推送至微信的实现方法
2018/08/13 Python
python 通过麦克风录音 生成wav文件的方法
2019/01/09 Python
python内置函数sorted()用法深入分析
2019/10/08 Python
Python爬虫爬取博客实现可视化过程解析
2020/06/29 Python
keras实现VGG16 CIFAR10数据集方式
2020/07/07 Python
CSS3 实现倒计时效果
2020/11/25 HTML / CSS
Lands’ End官网:经典的美国生活方式品牌
2016/08/14 全球购物
瑞典的玛丽小姐:Miss Mary of Sweden
2019/02/13 全球购物
学院书画协会部门岗位职责
2013/12/01 职场文书
七年级数学教学反思
2014/01/22 职场文书
安康杯竞赛活动总结
2014/05/05 职场文书
公务员考察材料
2014/12/23 职场文书
护士实习自荐信
2015/03/06 职场文书
Go语言-为什么返回值为接口类型,却返回结构体
2021/04/24 Golang
从QQtabBar看css命名规范BEM的详细介绍
2021/08/07 HTML / CSS
SpringCloud超详细讲解Feign声明式服务调用
2022/06/21 Java/Android