浅析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下阻止表单重复提交、防刷新、防后退
Aug 17 Javascript
input按钮的事件处理大全
Dec 10 Javascript
jQuery AjaxQueue改进步骤
Oct 06 Javascript
jquery 操作DOM的基本用法分享
Apr 05 Javascript
Express作者TJ告别Node.js奔向Go
Jul 14 Javascript
JavaScript定时器实现的原理分析
Dec 06 Javascript
Vue关于数据绑定出错解决办法
May 15 Javascript
使用Dropzone.js上传的示例代码
Oct 10 Javascript
用Node编写RESTful API接口的示例代码
Jul 04 Javascript
vue组件数据传递、父子组件数据获取,slot,router路由功能示例
Mar 19 Javascript
JS中的算法与数据结构之队列(Queue)实例详解
Aug 20 Javascript
Vue使用Element实现增删改查+打包的步骤
Nov 25 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 生成WML页面方法详解
2009/08/09 PHP
劣质的PHP代码简化
2010/02/08 PHP
PHP执行zip与rar解压缩方法实现代码
2010/12/05 PHP
PHP面向对象三大特点学习(充分理解抽象、封装、继承、多态)
2012/05/07 PHP
php保存任意网络图片到服务器的方法
2015/04/14 PHP
php+ajax实现无刷新数据分页的办法
2015/11/02 PHP
gearman中worker常驻后台,导致MySQL server has gone away的解决方法
2020/02/27 PHP
jquery 追加tr和删除tr示例代码
2013/09/12 Javascript
页面载入结束自动调用js函数示例
2013/09/23 Javascript
Jquery ajax执行顺序 返回自定义错误信息(实例讲解)
2013/11/06 Javascript
sails框架的学习指南
2014/12/22 Javascript
Jquery中offset()和position()的区别分析
2015/02/05 Javascript
jquery按回车键实现表单提交的简单实例
2016/05/25 Javascript
微信小程序 Flex布局详解
2016/10/09 Javascript
Javascript 闭包详解及实例代码
2016/11/30 Javascript
JS作用域闭包、预解释和this关键字综合实例解析
2016/12/16 Javascript
jQuery与js实现颜色渐变的方法
2016/12/30 Javascript
微信小程序 swiper制作tab切换实现附源码
2017/01/21 Javascript
基于JS实现移动端向左滑动出现删除按钮功能
2017/02/22 Javascript
vue监听input标签的value值方法
2018/08/27 Javascript
微信小程序中转义字符的处理方法
2019/03/28 Javascript
详解Vue-cli3.X使用px2rem遇到的问题
2019/08/09 Javascript
微信浏览器下拉黑边解决方案 wScroollFix
2020/01/21 Javascript
Element Carousel 走马灯的具体实现
2020/07/26 Javascript
Python回调函数用法实例详解
2015/07/02 Python
python一键升级所有pip package的方法
2017/01/16 Python
快速了解python leveldb
2018/01/18 Python
Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
2018/03/19 Python
Python中浅拷贝copy与深拷贝deepcopy的简单理解
2018/10/26 Python
PyQt Qt Designer工具的布局管理详解
2019/08/07 Python
利用python绘制中国地图(含省界、河流等)
2020/09/21 Python
一款纯css3实现的漂亮的404页面的实例教程
2014/11/27 HTML / CSS
高中教师评语大全
2014/04/25 职场文书
同学聚会策划方案
2014/06/06 职场文书
TS 类型兼容教程示例详解
2022/09/23 Javascript
table设置超出部分隐藏,鼠标移上去显示全部内容的方法
2022/12/24 HTML / CSS