浅析AngularJs HTTP响应拦截器


Posted in Javascript onDecember 28, 2015

为何要用拦截器?

任何时候,如果我们想要为请求添加全局功能,例如身份认证、错误处理等,在请求发送给服务器之前或服务器返回时对其进行拦截,是比较好的实现手段。

 angularJs通过拦截器提供了一个从全局层面进行处理的途径.

 拦截器允许你:

通过实现 request 方法拦截请求: 该方法会在 $http 发送请求道后台之前执行,因此你可以修改配置或做其他的操作。该方法接收请求配置对象(request configuration object)作为参数,然后必须返回配置对象或者 promise 。如果返回无效的配置对象或者 promise 则会被拒绝,导致 $http 调用失败。

通过实现 response 方法拦截响应: 该方法会在 $http 接收到从后台过来的响应之后执行,因此你可以修改响应或做其他操作。该方法接收响应对象(response object)作为参数,然后必须返回响应对象或者 promise。响应对象包括了请求配置(request configuration),头(headers),状态(status)和从后台过来的数据(data)。如果返回无效的响应对象或者 promise 会被拒绝,导致$http 调用失败。

通过实现 requestError 方法拦截请求异常: 有时候一个请求发送失败或者被拦截器拒绝了。请求异常拦截器会俘获那些被上一个请求拦截器中断的请求。它可以用来恢复请求或者有时可以用来撤销请求之前所做的配置,比如说关闭进度条,激活按钮和输入框什么之类的。

通过实现 responseError 方法拦截响应异常: 有时候我们后台调用失败了。也有可能它被一个请求拦截器拒绝了,或者被上一个响应拦截器中断了。在这种情况下,响应异常拦截器可以帮助我们恢复后台调用。

 拦截器的核心是服务工厂,通过向$httpprovider.interceptors数组中添加服务工厂。在$httpProvider中进行注册。

 angularJs提供四种拦截器,其中两种成功拦截器(request、response),两种失败拦截器(requestError、responseError)。

  在服务中添加一种或多种拦截器:

angular.module("myApp", []) 
  .factory('httpInterceptor', [ '$q', '$injector',function($q, $injector) { 
    var httpInterceptor = { 
      'responseError' : function(response) { 
        ...... 
        return $q.reject(response); 
      }, 
      'response' : function(response) { 
        ...... 
        return response; 
      }, 
      'request' : function(config) { 
        ...... 
        return config; 
      }, 
      'requestError' : function(config){ 
        ...... 
        return $q.reject(config); 
      } 
    } 
  return httpInterceptor; 
}

然后使用$httpProvider在.config()函数中注册拦截器

angular.module("myApp", []) 
.config([ '$httpProvider', function($httpProvider) { 
  $httpProvider.interceptors.push('httpInterceptor'); 
} ]);

  实际的例子:(对401、404的拦截)

routerApp.config([ '$httpProvider', function($httpProvider) { 
    $httpProvider.interceptors.push('httpInterceptor'); 
  } ]); 
  routerApp.factory('httpInterceptor', [ '$q', '$injector',function($q, $injector) { 
    var httpInterceptor = { 
      'responseError' : function(response) { 
        if (response.status == 401) { 
          var rootScope = $injector.get('$rootScope'); 
          var state = $injector.get('$rootScope').$state.current.name; 
          rootScope.stateBeforLogin = state; 
          rootScope.$state.go("login"); 
          return $q.reject(response); 
        } else if (response.status === 404) { 
          alert("404!"); 
          return $q.reject(response); 
        } 
      }, 
      'response' : function(response) { 
        return response; 
      } 
    } 
    return httpInterceptor; 
  }  
]);

Session 注入(请求拦截器)

这里有两种方式来实现服务端的认证。第一种是传统的 Cookie-Based 验证。通过服务端的 cookies 来对每个请求的用户进行认证。另一种方式是 Token-Based 验证。当用户登录时,他会从后台拿到一个 sessionToken。sessionToken 在服务端标识了每个用户,并且会包含在发送到服务端的每个请求中。

下面的 sessionInjector 为每个被俘获的请求添加了 x-session-token 头 (如果当前用户已登录):

<!-- lang: js -->
module.factory('sessionInjector', ['SessionService', function(SessionService) {
  var sessionInjector = {
    request: function(config) {
      if (!SessionService.isAnonymus) {
        config.headers['x-session-token'] = SessionService.token;
      }
      return config;
    }
  };
  return sessionInjector;
}]);
module.config(['$httpProvider', function($httpProvider) {
  $httpProvider.interceptors.push('sessionInjector');
}]);

然后创建一个请求:

<!-- lang: js -->
$http.get('https://api.github.com/users/naorye/repos');

被 sessionInjector 拦截之前的配置对象是这样的:

<!-- lang: js -->
{
  "transformRequest": [
    null
  ],
  "transformResponse": [
    null
  ],
  "method": "GET",
  "url": "https://api.github.com/users/naorye/repos",
  "headers": {
    "Accept": "application/json, text/plain, */*"
  }
}

被 sessionInjector 拦截之后的配置对象是这样的:

<!-- lang: js -->
{
  "transformRequest": [
    null
  ],
  "transformResponse": [
    null
  ],
  "method": "GET",
  "url": "https://api.github.com/users/naorye/repos",
  "headers": {
    "Accept": "application/json, text/plain, */*",
    "x-session-token": 415954427904
  }
}

以上内容给大家介绍了AngularJs HTTP响应拦截器的相关知识,希望本文分享能够给大家带来帮助。

Javascript 相关文章推荐
巧妙破除网页右键禁用的十大绝招
Aug 12 Javascript
javascript hasFocus使用实例
Jun 29 Javascript
js获取select标签选中值的两种方式
Jan 09 Javascript
js子页面获取父页面数据示例
May 15 Javascript
js根据鼠标移动速度背景图片自动旋转的方法
Feb 28 Javascript
jscript读写二进制文件的方法
Apr 22 Javascript
详解微信小程序 相对定位和绝对定位
May 11 Javascript
Angular ng-animate和ng-cookies用法详解
Apr 18 Javascript
微信小程序swiper实现滑动放大缩小效果
Nov 15 Javascript
js全屏事件fullscreenchange 实现全屏、退出全屏操作
Sep 17 Javascript
vue项目中使用bpmn-自定义platter的示例代码
May 11 Javascript
解决vue项目获取dom元素宽高总是不准确问题
Jul 29 Javascript
Bootstrap实现默认导航栏效果
Sep 21 #Javascript
Angularjs注入拦截器实现Loading效果
Dec 28 #Javascript
AngularJS进行性能调优的7个建议
Dec 28 #Javascript
浅析AngularJS Filter用法
Dec 28 #Javascript
jquery实现倒计时功能
Dec 28 #Javascript
基于jquery实现瀑布流布局
Jun 28 #Javascript
详解AngularJS Filter(过滤器)用法
Dec 28 #Javascript
You might like
基于文本的访客签到簿
2006/10/09 PHP
php程序之die调试法 快速解决错误
2009/09/17 PHP
php重定向的三种方法分享
2012/02/22 PHP
解析PHP中的内存管理,PHP动态分配和释放内存
2013/06/28 PHP
php session的应用详细介绍
2017/03/22 PHP
javascript来定义类的规范小结
2010/11/19 Javascript
基于JQuery的浮动DIV显示提示信息并自动隐藏
2011/02/11 Javascript
用js实现判断当前网址的来路如果不是指定的来路就跳转到指定页面
2011/05/02 Javascript
javascript中[]和{}对象使用介绍
2013/03/20 Javascript
js鼠标点击图片切换效果代码分享
2015/08/26 Javascript
javascript实现label标签跳出循环操作
2016/03/06 Javascript
原生js和css实现图片轮播效果
2017/02/07 Javascript
React服务端渲染(总结)
2017/07/01 Javascript
JavaScript的查询机制LHS和RHS解析
2019/08/16 Javascript
如何利用node.js开发一个生成逐帧动画的小工具
2019/12/01 Javascript
python实现巡检系统(solaris)示例
2014/04/02 Python
机器学习实战之knn算法pandas
2019/06/22 Python
python GUI库图形界面开发之PyQt5表格控件QTableView详细使用方法与实例
2020/03/01 Python
Python 定义只读属性的实现方式
2020/03/05 Python
关于python中的xpath解析定位
2020/03/06 Python
使用python实现CGI环境搭建过程解析
2020/04/28 Python
浅谈django框架集成swagger以及自定义参数问题
2020/07/07 Python
Pandas的数据过滤实现
2021/01/15 Python
CSS3样式linear-gradient的使用实例
2017/01/16 HTML / CSS
css3与html5实现响应式导航菜单(导航栏)效果分享
2014/02/12 HTML / CSS
利用html5 file api读取本地文件示例(如图片、PDF等)
2018/03/07 HTML / CSS
英国最大的正宗复古足球衫制造商和零售商:TOFFS
2018/06/21 全球购物
孕妇内衣和胸罩:Cake Maternity
2018/07/16 全球购物
英国时尚泳装品牌:Maru Swimwear
2019/10/06 全球购物
投资合作协议书
2014/04/17 职场文书
银行求职自荐信
2014/06/30 职场文书
机关党总支领导班子整改方案
2014/09/20 职场文书
2015年银行工作总结范文
2015/04/01 职场文书
2015年教师师德师风承诺书
2015/04/28 职场文书
董事长秘书工作总结
2015/08/14 职场文书
MySQL中VARCHAR与CHAR格式数据的区别
2021/05/26 MySQL