浅析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 相关文章推荐
jquery 多行滚动代码(附详细解释)
Jun 17 Javascript
jquery插件validate验证的小例子
May 08 Javascript
js判断输入是否为数字的具体实例
Aug 03 Javascript
子页向父页传值示例
Nov 27 Javascript
js获取字符串最后一位方法汇总
Nov 13 Javascript
js检测iframe是否加载完成的方法
Nov 26 Javascript
学习使用AngularJS文件上传控件
Feb 16 Javascript
vuejs选中当前样式active的实例
Aug 22 Javascript
JS实现字符串翻转的方法分析
Aug 31 Javascript
JavaScript复制变量三种方法实例详解
Jan 09 Javascript
element el-tree组件的动态加载、新增、更新节点的实现
Feb 27 Javascript
antd-DatePicker组件获取时间值,及相关设置方式
Oct 27 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
在“咖啡之国”感受咖啡文化
2021/03/03 咖啡文化
php,不用COM,生成excel文件
2006/10/09 PHP
PHP下使用mysqli的函数连接mysql出现warning: mysqli::real_connect(): (hy000/1040): ...
2016/02/14 PHP
PHP扩展框架之Yaf框架的安装与使用
2016/05/18 PHP
通过 Dom 方法提高 innerHTML 性能
2008/03/26 Javascript
javascript高级选择器querySelector和querySelectorAll全面解析
2016/04/07 Javascript
jQuery 全选 全部选 反选 实现代码
2016/08/17 Javascript
jQuery实现扑克正反面翻牌效果
2017/03/10 Javascript
详解Windows下安装Nodejs步骤
2017/05/18 NodeJs
vue+node+webpack环境搭建教程
2017/11/05 Javascript
javascript用rem来做响应式开发
2018/01/13 Javascript
webpack热模块替换(HMR)/热更新的方法
2018/04/05 Javascript
JavaScript笛卡尔积超简单实现算法示例
2018/07/30 Javascript
Vue 中对图片地址进行拼接的方法
2018/09/03 Javascript
为jquery的ajax请求添加超时timeout时间的操作方法
2018/09/04 jQuery
微信小程序image图片加载完成监听
2019/08/31 Javascript
vue.js+ElementUI实现进度条提示密码强度效果
2020/01/18 Javascript
python爬虫教程之爬取百度贴吧并下载的示例
2014/03/07 Python
tensorflow 加载部分变量的实例讲解
2018/07/27 Python
解决django前后端分离csrf验证的问题
2019/02/03 Python
3行Python代码实现图像照片抠图和换底色的方法
2019/10/10 Python
Tensorflow: 从checkpoint文件中读取tensor方式
2020/02/10 Python
django-利用session机制实现唯一登录的例子
2020/03/16 Python
pycharm专业版远程登录服务器的详细教程
2020/09/15 Python
调用HTML5的Canvas API绘制图形的快速入门指南
2016/06/17 HTML / CSS
Myprotein瑞典官方网站:畅销欧洲英国运动营养品牌
2018/01/22 全球购物
澳大利亚在线家具、灯饰和家居装饰店:LivingStyles
2018/11/20 全球购物
介绍一下Transact-SQL中SPACE函数的用法
2015/09/01 面试题
什么是Oracle的后台进程background processes?都有哪些后台进程?
2012/04/26 面试题
Java基础类库面试题
2013/09/04 面试题
大学生职业生涯规划书的基本内容
2014/01/06 职场文书
2016应届毕业生自荐信范文
2016/01/28 职场文书
《折线统计图》教学反思
2016/02/22 职场文书
浅谈Mysql多表连接查询的执行细节
2021/04/24 MySQL
8g内存用python读取10文件_面试题-python 如何读取一个大于 10G 的txt文件?
2021/05/28 Python
Vue 打包后相对路径的引用问题
2022/06/05 Vue.js