浅析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 相关文章推荐
Dom与浏览器兼容性说明
Oct 25 Javascript
汉化英文版的Dreamweaver CS5并自动提示jquery
Nov 25 Javascript
原生js实现跨浏览器获取鼠标按键的值
Apr 08 Javascript
jquery实现微博文字输入框 输入时显示输入字数 效果实现
Jul 12 Javascript
js父窗口关闭时子窗口随之关闭完美解决方案
Apr 29 Javascript
javascript闭包入门示例
Apr 30 Javascript
完善的jquery处理机制
Feb 21 Javascript
浅谈原型对象的常用开发模式
Jul 22 Javascript
node.js基础知识小结
Feb 26 Javascript
浅谈Angularjs中不同类型的双向数据绑定
Jul 16 Javascript
IE9 elementUI文件上传的问题解决
Oct 17 Javascript
vue实现将数据存入vuex中以及从vuex中取出数据
Nov 08 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连接mysql数据库代码
2009/03/10 PHP
php输出xml必须header的解决方法
2014/10/17 PHP
PHP之浮点数计算比较以及取整数不准确的解决办法
2015/07/29 PHP
PDO::errorCode讲解
2019/01/28 PHP
jquery实现心算练习代码
2010/12/06 Javascript
jquery中常用的SET和GET$(”#msg”).html循环介绍
2013/10/09 Javascript
jquery实现用户信息修改验证输入方法汇总
2015/07/18 Javascript
10个JavaScript中易犯小错误
2016/02/14 Javascript
Javascript 普通函数和构造函数的区别
2016/11/05 Javascript
js中获取键盘按下键值event.keyCode、event.charCode和event.which的兼容性详解
2017/03/15 Javascript
AngularJS 最常用的八种功能(基础知识)
2017/06/26 Javascript
JavaScript循环_动力节点Java学院整理
2017/06/28 Javascript
Vue from-validate 表单验证的示例代码
2017/09/26 Javascript
解决在vue项目中webpack打包后字体不生效的问题
2018/09/01 Javascript
详解vuex之store拆分即多模块状态管理(modules)篇
2018/11/13 Javascript
python不换行之end=与逗号的意思及用途
2017/11/21 Python
windows下cx_Freeze生成Python可执行程序的详细步骤
2018/10/09 Python
Python人工智能之路 jieba gensim 最好别分家之最简单的相似度实现
2019/08/13 Python
解决Tensorflow 内存泄露问题
2020/02/05 Python
Django使用rest_framework写出API
2020/05/21 Python
完美解决TensorFlow和Keras大数据量内存溢出的问题
2020/07/03 Python
利用python批量爬取百度任意类别的图片的实现方法
2020/10/07 Python
Django haystack实现全文搜索代码示例
2020/11/28 Python
python中字符串的编码与解码详析
2020/12/03 Python
CSS3点击按钮实现背景渐变动画效果
2016/10/19 HTML / CSS
迪卡侬印度官网:购买所有体育用品
2017/06/24 全球购物
LVMH旗下最大的奢侈品网站平台:24S
2020/05/24 全球购物
非常详细的C#面试题集
2016/07/13 面试题
小学校园活动策划
2014/01/30 职场文书
社区党建工作方案
2014/06/10 职场文书
机械电子工程专业自荐书
2014/06/10 职场文书
启动仪式策划方案
2014/06/14 职场文书
赵乐秦在党的群众路线教育实践活动总结大会上的讲话稿
2014/10/25 职场文书
党员转正申请报告
2015/05/15 职场文书
MYSQL主从数据库同步备份配置的方法
2021/05/26 MySQL
关于JavaScript 中 if包含逗号表达式
2021/11/27 Javascript