浅析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 相关文章推荐
form表单只提交数据而不进行页面跳转的解决方案
Sep 18 Javascript
JavaScript中对象介绍
Dec 31 Javascript
Angular.js与Bootstrap相结合实现手风琴菜单代码
Apr 13 Javascript
easy ui datagrid 从编辑框中获取值的方法
Feb 22 Javascript
JavaScript实现三级联动菜单效果
Aug 16 Javascript
快速处理vue渲染前的显示问题
Mar 05 Javascript
基于node搭建服务器,写接口,调接口,跨域的实例
May 13 Javascript
vue-cli和v-charts实现可视化图表过程解析
Oct 08 Javascript
JS removeAttribute()方法实现删除元素的某个属性
Jan 11 Javascript
Vue 实例中使用$refs的注意事项
Jan 29 Vue.js
在vue中import()语法不能传入变量的问题及解决
Apr 01 Vue.js
vue3种table表格选项个数的控制方法
Apr 14 Vue.js
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 字符串操作入门教程
2006/12/06 PHP
php中文乱码怎么办如何让浏览器自动识别utf-8
2014/01/15 PHP
PHP使用SOAP扩展实现WebService的方法
2016/04/01 PHP
yii2整合百度编辑器umeditor及umeditor图片上传问题的解决办法
2016/04/20 PHP
PHP仿微信多图片预览上传实例代码
2016/09/13 PHP
php rmdir使用递归函数删除非空目录实例详解
2016/10/20 PHP
PHP实现权限管理功能示例
2017/09/22 PHP
PHP实时统计中文字数和区别
2019/02/28 PHP
利用js跨页面保存变量做菜单的方法
2008/01/17 Javascript
JavaScript iframe的相互操作浅析
2009/10/14 Javascript
javascript 处理事件绑定的一些兼容写法
2009/12/24 Javascript
Flexigrid在IE下不显示数据的有效处理方法
2014/09/04 Javascript
JavaScript笔记之数据属性和存储器属性
2016/03/31 Javascript
JS中script标签defer和async属性的区别详解
2016/08/12 Javascript
jquery的父、子、兄弟节点查找,节点的子节点循环方法
2016/12/07 Javascript
JS常见创建类的方法小结【工厂方式,构造器方式,原型方式,联合方式等】
2017/04/01 Javascript
vue.js实现备忘录功能的方法
2017/07/10 Javascript
小程序根据手机机型设置自定义底部导航距离
2019/06/04 Javascript
微信js-sdk 录音功能的示例代码
2019/11/01 Javascript
Vue SSR 即时编译技术的实现
2020/05/06 Javascript
Vue2.0 ES6语法降级ES5的操作
2020/10/30 Javascript
python中的break、continue、exit()、pass全面解析
2017/08/05 Python
django请求返回不同的类型图片json,xml,html的实例
2018/05/22 Python
儿童学习python的一些小技巧
2018/05/27 Python
python爬取百度贴吧前1000页内容(requests库面向对象思想实现)
2019/08/10 Python
Tensorflow 实现释放内存
2020/02/03 Python
深入剖析webstorage[html5的本地数据处理]
2016/07/11 HTML / CSS
HTML5的一个显示电池状态的API简介
2015/06/18 HTML / CSS
德国便宜的宠物店:Brekz.de
2020/10/23 全球购物
外贸业务员工作职责
2014/01/06 职场文书
自我鉴定注意事项
2014/01/19 职场文书
企业文化标语口号
2014/06/09 职场文书
学雷锋志愿者活动总结
2014/06/27 职场文书
教师批评与自我批评心得体会
2014/10/16 职场文书
博士论文答辩开场白
2015/06/01 职场文书
muduo TcpServer模块源码分析
2022/04/26 Redis