浅析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 相关文章推荐
Ajax+Json 级联菜单实现代码
Oct 27 Javascript
jquery UI 1.72 之datepicker
Dec 29 Javascript
JavaScript高级程序设计阅读笔记(十六) javascript检测浏览器和操作系统-detect.js
Aug 14 Javascript
分享jQuery网页元素拖拽插件
Dec 01 Javascript
微信小程序  TLS 版本必须大于等于1.2问题解决
Feb 22 Javascript
详解webpack介绍&amp;安装&amp;常用命令
Jun 29 Javascript
微信小程序实现滚动消息通知
Feb 02 Javascript
详解JSON和JSONP劫持以及解决方法
Mar 08 Javascript
ES6 Array常用扩展的应用实例分析
Jun 26 Javascript
vue点击页面空白处实现保存功能
Nov 06 Javascript
vue项目中使用particles实现粒子背景效果及遇到的坑(按钮没有点击响应)
Feb 11 Javascript
JavaScript小技巧带你提升你的代码技能
Sep 15 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
PHP 基于文件头的文件类型验证类函数
2012/05/01 PHP
深入解析PHP中foreach语句控制数组循环的用法
2015/11/30 PHP
php获取指定数量随机字符串的方法
2017/02/06 PHP
PHP isset()与empty()的使用区别详解
2017/02/10 PHP
Laravel框架使用Seeder实现自动填充数据功能
2018/06/13 PHP
Jquery调用webService远程访问出错的解决方法
2010/05/21 Javascript
用javascript模仿ie的自动完成类似自动完成功的表单
2012/12/12 Javascript
获取数组中最大最小值方法js代码(自写)
2013/08/12 Javascript
JS生成随机字符串的多种方法
2014/06/10 Javascript
Javascript学习笔记之函数篇(四):arguments 对象
2014/11/23 Javascript
jquery中checkbox全选失效的解决方法
2014/12/26 Javascript
jquery实现Ctrl+Enter提交表单的方法
2015/07/21 Javascript
JavaScript中setTimeout和setInterval函数的传参及调用
2016/03/11 Javascript
JavaScript中transform实现数字翻页效果
2017/03/08 Javascript
bootstrap是什么_动力节点Java学院整理
2017/07/14 Javascript
小程序开发基础之view视图容器
2018/08/21 Javascript
在vue中使用axios实现post方式获取二进制流下载文件(实例代码)
2019/12/16 Javascript
基于vue.js实现购物车
2020/01/15 Javascript
Python3实现连接SQLite数据库的方法
2014/08/23 Python
跟老齐学Python之有容乃大的list(3)
2014/09/15 Python
分析在Python中何种情况下需要使用断言
2015/04/01 Python
ansible作为python模块库使用的方法实例
2017/01/17 Python
django 常用orm操作详解
2017/09/13 Python
Python编程之基于概率论的分类方法:朴素贝叶斯
2017/11/11 Python
Selenium鼠标与键盘事件常用操作方法示例
2018/08/13 Python
python3+requests接口自动化session操作方法
2018/10/13 Python
python通过ffmgep从视频中抽帧的方法
2018/12/05 Python
在python中画正态分布图像的实例
2019/07/08 Python
python进程间通信Queue工作过程详解
2019/11/01 Python
Django choices下拉列表绑定实例
2020/03/13 Python
全球领先美式家具品牌:Ashley爱室丽家居
2017/08/07 全球购物
美国首屈一指的礼品篮供应商:GiftTree
2018/01/06 全球购物
教师党员公开承诺书
2014/03/25 职场文书
涉及车辆房产分割的离婚协议书范文
2014/10/12 职场文书
中学生思想品德评语
2014/12/31 职场文书
python三子棋游戏
2022/05/04 Python