浅析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 相关文章推荐
js 替换
Feb 19 Javascript
Jquery实现Div上下移动示例
Apr 23 Javascript
js数组的操作指南
Dec 28 Javascript
JQuery的Pager分页器实现代码
May 03 Javascript
JS实现图片剪裁并预览效果
Aug 12 Javascript
AngularJS入门教程之过滤器详解
Aug 19 Javascript
bootstrap modal+gridview实现弹出框效果
Aug 15 Javascript
javascript高仿热血传奇游戏实现代码
Feb 22 Javascript
angularJs中ng-model-options设置数据同步的方法
Sep 30 Javascript
微信小程序事件对象中e.target和e.currentTarget的区别详解
May 08 Javascript
JS实现的简单tab切换功能完整示例
Jun 20 Javascript
vue父子组件间引用之$parent、$children
May 20 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
WordPress中用于检索模版的相关PHP函数使用解析
2015/12/15 PHP
Yii2搭建后台并实现rbac权限控制完整实例教程
2016/04/28 PHP
深入理解PHP类的自动载入机制
2016/09/16 PHP
PHP给源代码加密的几种方法汇总(推荐)
2018/02/06 PHP
正则表达式判断是否存在中文和全角字符和判断包含中文字符串长度
2008/09/27 Javascript
JQuery for与each性能比较分析
2013/05/14 Javascript
js获取事件源及触发该事件的对象
2013/10/24 Javascript
JS对象与json字符串格式转换实例
2014/10/28 Javascript
jQuery实现指定区域外单击关闭指定层的方法【经典】
2016/06/22 Javascript
实现隔行换色效果的两种方式【实用】
2016/11/27 Javascript
Bootstrap基本组件学习笔记之缩略图(13)
2016/12/08 Javascript
如何利用JQuery实现从底部回到顶部的功能
2016/12/27 Javascript
get  post jsonp三种数据交互形式实例详解
2017/08/25 Javascript
vue.js 实现输入框动态添加功能
2018/06/25 Javascript
vue.js实现带日期星期的数字时钟功能示例
2018/08/28 Javascript
js实现拾色器插件(ColorPicker)
2020/05/21 Javascript
Vue+element+cookie记住密码功能的简单实现方法
2020/09/20 Javascript
Python+Socket实现基于UDP协议的局域网广播功能示例
2017/08/31 Python
python实现csv格式文件转为asc格式文件的方法
2018/03/23 Python
python3+PyQt5实现拖放功能
2018/04/24 Python
pygame游戏之旅 调用按钮实现游戏开始功能
2018/11/21 Python
python+selenium实现简历自动刷新的示例代码
2019/05/20 Python
Python+AutoIt实现界面工具开发过程详解
2019/08/07 Python
opencv python图像梯度实例详解
2020/02/04 Python
业务员岗位职责范本
2013/12/15 职场文书
初一英语教学反思
2014/01/11 职场文书
餐厅考勤管理制度
2014/01/28 职场文书
新任教师自我鉴定
2014/02/24 职场文书
关于环保的活动方案
2014/08/25 职场文书
导航工程专业自荐信
2014/09/02 职场文书
高校师德师风自我剖析材料
2014/09/29 职场文书
初中作文评语集锦
2014/12/25 职场文书
2015年端午节活动策划书
2015/05/05 职场文书
感恩教育观后感
2015/06/17 职场文书
学生会2016感恩节活动小结
2016/04/01 职场文书
Matlab如何实现矩阵复制扩充
2021/06/02 Python