详解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 相关文章推荐
JavaScript中的null和undefined解析
Apr 14 Javascript
幻灯片带网页设计中的20个奇妙应用示例小结
May 27 Javascript
js 控制下拉菜单刷新的方法
Mar 03 Javascript
js取消单选按钮选中并判断对象是否为空
Nov 14 Javascript
javascript右下角弹层及自动隐藏(自己编写)
Nov 20 Javascript
JavaScript常用的弹出广告及背投广告实现方法
Feb 06 Javascript
你知道setTimeout是如何运行的吗?
Aug 16 Javascript
JavaScript每天必学之事件
Sep 18 Javascript
基于JavaScript实现验证码功能
Apr 01 Javascript
详解vue+vueRouter+webpack的简单实例
Jun 17 Javascript
vue + typescript + video.js实现 流媒体播放 视频监控功能
Jul 07 Javascript
JavaScript实现点击出现子菜单效果
Feb 08 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将向Java靠拢
2006/10/09 PHP
[原创]效率较高的php下读取文本文件的代码
2008/07/02 PHP
ThinkPHP3.1新特性之动态设置自动完成和自动验证示例
2014/06/19 PHP
PHP实现阿里大鱼短信验证的实例代码
2017/07/10 PHP
JavaScript 设计模式之组合模式解析
2010/04/09 Javascript
25个优雅的jQuery Tooltip插件推荐
2011/05/25 Javascript
跨浏览器的事件对象介绍
2012/06/27 Javascript
浅析JS刷新框架中的其他页面 && JS刷新窗口方法汇总
2013/07/08 Javascript
jQuery 过滤方法filter()选择具有特殊属性的元素
2014/06/15 Javascript
js弹出对话框方式小结
2015/11/17 Javascript
灵活的理解JavaScript中的this指向
2016/02/25 Javascript
详解使用fetch发送post请求时的参数处理
2017/04/05 Javascript
微信小程序支付之c#后台实现方法
2017/10/19 Javascript
浅谈gulp创建完整的项目流程
2017/12/20 Javascript
了解javascript中变量及函数的提升
2019/05/27 Javascript
微信小程序修改checkbox的样式代码实例
2020/01/21 Javascript
Vue动态加载图片在跨域时无法显示的问题及解决方法
2020/03/10 Javascript
使用vue实现HTML页面生成图片的方法
2020/03/12 Javascript
使用React代码动态生成栅格布局的方法
2020/05/24 Javascript
Paypal支付不完全指北
2020/06/04 Javascript
axios解决高并发的方法:axios.all()与axios.spread()的操作
2020/11/09 Javascript
[59:15]EG vs LGD 2018国际邀请赛淘汰赛BO3 第一场 8.26
2018/08/29 DOTA
Python自定义函数的创建、调用和函数的参数详解
2014/03/11 Python
python 爬虫出现403禁止访问错误详解
2017/03/11 Python
python中 chr unichr ord函数的实例详解
2017/08/06 Python
动态规划之矩阵连乘问题Python实现方法
2017/11/27 Python
在Django下测试与调试REST API的方法详解
2019/08/29 Python
解决margin 外边距合并问题
2019/07/03 HTML / CSS
阿拉伯世界最大的电子商务网站:Souq沙特阿拉伯
2016/10/28 全球购物
品质主管的岗位职责
2013/12/04 职场文书
门卫人员岗位职责
2013/12/24 职场文书
雪山饭庄的创业计划书范文
2014/01/18 职场文书
会计电算化大学生职业规划书
2014/02/05 职场文书
授权收款委托书
2014/09/23 职场文书
html2 canvas svg不能识别的解决方案
2021/06/03 HTML / CSS
8个JS的reduce使用实例和reduce操作方式
2021/10/05 Javascript