浅析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 相关文章推荐
javascript 选择文件夹对话框(web)
Jul 07 Javascript
JavaScript中实现异步编程模式的4种方法
Sep 24 Javascript
javascript实现网页子页面遍历回调的方法(涉及 window.frames、递归函数、函数上下文)
Jul 27 Javascript
用js实现放大镜的效果的简单实例
May 23 Javascript
高效Web开发的10个jQuery代码片段
Jul 22 Javascript
jQuery实现邮箱下拉列表自动补全功能
Sep 08 Javascript
JS使用数组实现的队列功能示例
Mar 04 Javascript
js如何获取图片url的Blob值并预览示例代码
Mar 07 Javascript
react-native滑动吸顶效果的实现过程
Jun 03 Javascript
JS数组降维的实现Array.prototype.concat.apply([], arr)
Apr 28 Javascript
JavaScript中的全局属性与方法深入解析
Jun 14 Javascript
Javascript Symbol原理及使用方法解析
Oct 22 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
linux下使用ThinkPHP需要注意大小写导致的问题
2011/08/02 PHP
老生常谈PHP数组函数array_merge(必看篇)
2017/05/25 PHP
理解JavaScript中的对象 推荐
2011/01/09 Javascript
基于Jquery与WebMethod投票功能实现代码
2011/01/19 Javascript
jquery Mobile入门—外部链接切换示例代码
2013/01/08 Javascript
Nodejs中读取中文文件编码问题、发送邮件和定时任务实例
2015/01/01 NodeJs
JavaScript 动态加载脚本和样式的方法
2015/04/13 Javascript
针对初学者的jQuery入门指南
2015/08/15 Javascript
Sublime Text 3常用插件及安装方法
2015/12/16 Javascript
JS生成某个范围的随机数【四种情况详解】
2016/04/20 Javascript
AngularJS表单详解及示例代码
2016/08/17 Javascript
JavaScript获取select中text值的方法
2017/02/13 Javascript
jQuery实现贪吃蛇小游戏(附源码下载)
2017/03/04 Javascript
JavaScript基于对象方法实现数组去重及排序操作示例
2018/07/10 Javascript
vue 监听键盘回车事件详解 @keyup.enter || @keyup.enter.native
2018/08/25 Javascript
微信小程序中的canvas 文字断行和省略号显示功能的处理方法
2018/11/14 Javascript
vue实现文字横向无缝走马灯组件效果的实例代码
2019/04/09 Javascript
vue-cli的build的文件夹下没有dev-server.js文件配置mock数据的方法
2019/04/17 Javascript
Python的Tornado框架的异步任务与AsyncHTTPClient
2016/06/27 Python
Python 基础教程之包和类的用法
2017/02/23 Python
遗传算法之Python实现代码
2017/10/10 Python
python入门:这篇文章带你直接学会python
2018/09/14 Python
Python利用matplotlib做图中图及次坐标轴的实例
2019/07/08 Python
python实现广度优先搜索过程解析
2019/10/19 Python
python redis 批量设置过期key过程解析
2019/11/26 Python
详解Python中字符串前“b”,“r”,“u”,“f”的作用
2019/12/18 Python
python给图像加上mask,并提取mask区域实例
2020/01/19 Python
python中watchdog文件监控与检测上传功能
2020/10/30 Python
python使用Windows的wmic命令监控文件运行状况,如有异常发送邮件报警
2021/01/30 Python
css3+伪元素实现鼠标移入时下划线向两边展开的效果
2017/04/25 HTML / CSS
如何使用css3实现一个类在线直播的队列动画的示例代码
2020/06/17 HTML / CSS
使用HTML5 Canvas API绘制弧线的教程
2016/03/22 HTML / CSS
幼儿园父亲节活动方案
2014/03/11 职场文书
厉行勤俭节约倡议书
2014/05/16 职场文书
优秀团支部申报材料
2014/12/26 职场文书
Django开发RESTful API实现增删改查(入门级)
2021/05/10 Python