浅析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 相关文章推荐
关闭时刷新父窗口两种方法
May 07 Javascript
JS实现完全语义化的网页选项卡效果代码
Sep 15 Javascript
基于jQuery实现收缩展开功能
Mar 18 Javascript
浅谈jquery设置和获得checkbox选中的问题
Aug 19 Javascript
Javascript中的 “&amp;” 和 “|” 详解
Feb 02 Javascript
JS正则表达式判断有效数实例代码
Mar 13 Javascript
vue--点击当前增加class,其他删除class的方法
Sep 15 Javascript
javascript中的闭包概念与用法实践分析
Jul 26 Javascript
node读写Excel操作实例分析
Nov 06 Javascript
bootstrap实现嵌套模态框的实例代码
Jan 10 Javascript
js实现弹幕墙效果
Dec 10 Javascript
JavaScript 反射学习技巧
Oct 16 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 获取当前访问的url文件名的方法小结
2010/02/08 PHP
CentOS下PHP安装Oracle扩展
2015/02/15 PHP
php使用simplexml_load_file加载XML文件并显示XML的方法
2015/03/19 PHP
WordPress中使主题支持小工具以及添加插件启用函数
2015/12/22 PHP
我整理的PHP 7.0主要新特性
2016/01/07 PHP
PHP运行模式汇总
2016/11/06 PHP
js跑步算法的实现代码
2013/12/04 Javascript
js 通用订单代码
2013/12/23 Javascript
基于NodeJS的前后端分离的思考与实践(一)全栈式开发
2014/09/26 NodeJs
JavaScript实现表格点击排序的方法
2015/05/11 Javascript
JavaScript操作Cookie方法实例分析
2015/05/27 Javascript
fullCalendar中文API官方文档
2017/02/07 Javascript
vue2 中如何实现动态表单增删改查实例
2017/06/09 Javascript
vue不通过路由直接获取url中参数的方法示例
2017/08/24 Javascript
Windows下Node爬虫神器Puppeteer安装记
2019/01/09 Javascript
仿ElementUI实现一个Form表单的实现代码
2019/04/23 Javascript
vue日历/日程提醒/html5本地缓存功能
2019/09/02 Javascript
Vue时间轴 vue-light-timeline的用法说明
2020/10/29 Javascript
[04:09]显微镜下的DOTA2第十二期—NaVi美如画的团战
2014/06/23 DOTA
Python SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)
2014/05/06 Python
Python3 获取一大段文本之间两个关键字之间的内容方法
2018/10/11 Python
Python实现获取汉字偏旁部首的方法示例【测试可用】
2018/12/18 Python
AUC计算方法与Python实现代码
2020/02/28 Python
通过Canvas及File API缩放并上传图片完整示例
2013/08/08 HTML / CSS
html5实现多图片预览上传及点击可拖拽控件
2018/03/15 HTML / CSS
Html5之webcoekt播放JPEG图片流
2020/09/22 HTML / CSS
飞利浦比利时官方网站:Philips比利时
2016/08/24 全球购物
匡威比利时官网:Converse Belgium
2017/04/13 全球购物
澳大利亚在线高跟鞋商店:Shoe Me
2019/11/19 全球购物
初中同学聚会邀请函
2014/02/03 职场文书
本科应届生自荐信
2014/06/29 职场文书
销售员工作检讨书(推荐篇)
2014/10/18 职场文书
2015高考寄语集锦
2015/02/27 职场文书
MySQL派生表联表查询实战过程
2022/03/20 MySQL
JavaScript中的LHS和RHS分析详情
2022/04/06 Javascript