详解AngularJs HTTP响应拦截器实现登陆、权限校验


Posted in Javascript onApril 11, 2017

$httpAngularJS 的 $http 服务允许我们通过发送 HTTP 请求方式与后台进行通信。在某些情况下,我们希望可以俘获所有的请求,并且在将其发送到服务端之前进行操作。还有一些情况是,我们希望俘获响应,并且在完成完成调用之前处理它。一个很好例子就是处理全局 http 异常。拦截器(Interceptors)应运而生。本文将介绍 AngularJS 的拦截器,并且给几个有用的例子。

什么是拦截器?

$httpProvider 中有一个 interceptors 数组,而所谓拦截器只是一个简单的注册到了该数组中的常规服务工厂。下面的例子告诉你怎么创建一个拦截器:

<!-- lang: js -->
module.factory('myInterceptor', ['$log', function($log) {
  $log.debug('$log is here to show you that this is a regular factory with injection');

  var myInterceptor = {
    ....
    ....
    ....
  };

  return myInterceptor;
}]);

然后通过它的名字添加到 $httpProvider.interceptors 数组:

<!-- lang: js -->
module.config(['$httpProvider', function($httpProvider) {
  $httpProvider.interceptors.push('myInterceptor');
}]);

拦截器允许你:

  1. 通过实现 request 方法拦截请求: 该方法会在 $http 发送请求道后台之前执行,因此你可以修改配置或做其他的操作。该方法接收请求配置对象(request configuration object)作为参数,然后必须返回配置对象或者 promise 。如果返回无效的配置对象或者 promise 则会被拒绝,导致 $http 调用失败。
  2. 通过实现 response 方法拦截响应: 该方法会在 $http 接收到从后台过来的响应之后执行,因此你可以修改响应或做其他操作。该方法接收响应对象(response object)作为参数,然后必须返回响应对象或者 promise。响应对象包括了请求配置(request configuration),头(headers),状态(status)和从后台过来的数据(data)。如果返回无效的响应对象或者 promise 会被拒绝,导致 $http 调用失败。
  3. 通过实现 requestError 方法拦截请求异常: 有时候一个请求发送失败或者被拦截器拒绝了。请求异常拦截器会俘获那些被上一个请求拦截器中断的请求。它可以用来恢复请求或者有时可以用来撤销请求之前所做的配置,比如说关闭进度条,激活按钮和输入框什么之类的。
  4. 通过实现 responseError 方法拦截响应异常: 有时候我们后台调用失败了。也有可能它被一个请求拦截器拒绝了,或者被上一个响应拦截器中断了。在这种情况下,响应异常拦截器可以帮助我们恢复后台调用。

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;
  }

因此,我们可以通过拦截器来判断用于的登陆与权限问题。

代码中的 $rootScope.user是登录后把用户信息放到了全局rootScope上,方便其他地方使用,$rootScope.defaultPage也是默认主页面,初始化的时候写死到rootScope里的。

$rootScope.$on('$stateChangeStart',function(event, toState, toParams, fromState, fromParams){
 if(toState.name=='login')return;// 如果是进入登录界面则允许
 // 如果用户不存在
 if(!$rootScope.user || !$rootScope.user.token){
 event.preventDefault();// 取消默认跳转行为
 $state.go("login",{from:fromState.name,w:'notLogin'});//跳转到登录界面
 }
});

另外还有用户已经登录,但是登录超时了,还有就是增加后台接口的判断来增强安全性。不能完全依靠本地逻辑

我们在model里面增加一个用户拦截器,在rensponseError中判断错误码,抛出事件让Contoller或view来处理

app.factory('UserInterceptor', ["$q","$rootScope",function ($q,$rootScope) {
 return {
    request:function(config){
      config.headers["TOKEN"] = $rootScope.user.token;
      return config;
    },
    responseError: function (response) {
      var data = response.data;
  // 判断错误码,如果是未登录
      if(data["errorCode"] == "500999"){
  // 清空用户本地token存储的信息,如果
        $rootScope.user = {token:""};
  // 全局事件,方便其他view获取该事件,并给以相应的提示或处理
        $rootScope.$emit("userIntercepted","notLogin",response);
      }
  // 如果是登录超时
  if(data["errorCode"] == "500998"){
        $rootScope.$emit("userIntercepted","sessionOut",response);
      }
      return $q.reject(response);
    }
  };
}]);

别忘了要注册拦截器到angularjs的config中哦

app.config(function ($httpProvider) {
  $httpProvider.interceptors.push('UserInterceptor');
});

最后在controller中处理错误事件

$rootScope.$on('userIntercepted',function(errorType){
  // 跳转到登录界面,这里我记录了一个from,这样可以在登录后自动跳转到未登录之前的那个界面
  $state.go("login",{from:$state.current.name,w:errorType});
});

最后还可以在loginController中做更多的细节处理

// 如果用户已经登录了,则立即跳转到一个默认主页上去,无需再登录
if($rootScope.user.token){
  $state.go($rootScope.defaultPage);
  return;
}

另外在登录成功回调后还可以跳转到上一次界面,也就是上面记录的from

var from = $stateParams["from"];
$state.go(from && from != "login" ? from : $rootScope.defaultPage);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Prototype Object对象 学习
Jul 12 Javascript
JavaScript 直接操作本地文件的实现代码
Dec 01 Javascript
JQuery 遮罩层实现(mask)实现代码
Jan 09 Javascript
Js+Jq获取URL参数的集中方法示例代码
May 20 Javascript
JavaScript实现生成GUID(全局统一标识符)
Sep 05 Javascript
Jquery 实现checkbox全选方法
Jan 28 Javascript
js代码实现下拉菜单【推荐】
Dec 15 Javascript
JavaScript 函数的定义-调用、注意事项
Apr 16 Javascript
vue.js模仿京东省市区三级联动的选择组件实例代码
Nov 22 Javascript
使用Angular CLI快速创建Angular项目的一些基本概念和写法小结
Apr 22 Javascript
简单了解JavaScript中的执行上下文和堆栈
Jun 24 Javascript
javascript单张多张图无缝滚动实例代码
May 10 Javascript
JavaScript数据结构中栈的应用之表达式求值问题详解
Apr 11 #Javascript
js 获取今天以及过去日期
Apr 11 #Javascript
javascript数据结构中栈的应用之符号平衡问题
Apr 11 #Javascript
javascript编程实现栈的方法详解【经典数据结构】
Apr 11 #Javascript
Bootstrap 3浏览器兼容性问题及解决方案
Apr 11 #Javascript
JS实现线性表的链式表示方法示例【经典数据结构】
Apr 11 #Javascript
JS实现线性表的顺序表示方法示例【经典数据结构】
Apr 11 #Javascript
You might like
动漫女神老婆无限好,但日本女生可能就不是这么一回事了!
2020/03/04 日漫
php在文件指定行中写入代码的方法
2012/05/23 PHP
PHP简单操作MongoDB的方法(安装及增删改查)
2016/05/26 PHP
php读取qqwry.dat ip地址定位文件的类实例代码
2016/11/15 PHP
PHP生成图片验证码功能示例
2017/01/12 PHP
PHP命名空间namespace及use的简单用法分析
2018/08/03 PHP
脚本吧 - 幻宇工作室用到js,超强推荐base.js
2006/12/23 Javascript
js arguments对象应用介绍
2012/11/28 Javascript
JavaScript String.replace函数参数实例说明
2013/06/06 Javascript
利用了jquery的ajax实现二级联互动菜单
2013/12/02 Javascript
用javascript关闭本窗口技巧小结
2014/09/05 Javascript
node.js超时timeout详解
2014/11/26 Javascript
浅谈Vue.js
2017/03/02 Javascript
基于Swiper实现移动端页面图片轮播效果
2017/12/28 Javascript
VUE2.0中Jsonp的使用方法
2018/05/22 Javascript
微信小程序自定义tabBar组件开发详解
2020/09/24 Javascript
详解关于webpack多入口热加载很慢的原因
2019/04/24 Javascript
vue抽出组件并传值实例
2020/07/31 Javascript
基于Vant UI框架实现时间段选择器
2020/12/24 Javascript
Python实现截屏的函数
2015/07/25 Python
Python中列表和元组的相关语句和方法讲解
2015/08/20 Python
python中解析json格式文件的方法示例
2017/05/03 Python
Python3使用PyQt5制作简单的画板/手写板实例
2017/10/19 Python
Python-while 计算100以内奇数和的方法
2019/06/11 Python
python 已知一个字符,在一个list中找出近似值或相似值实现模糊匹配
2020/02/29 Python
flask项目集成swagger的方法
2020/12/09 Python
美国从事品牌鞋类零售的连锁店:Famous Footwear
2016/08/25 全球购物
6PM官网:折扣鞋、服装及配饰
2018/08/03 全球购物
世界上最全面的草药补充剂和顶级品牌维生素网站:HerbsPro
2019/01/20 全球购物
新西兰杂志订阅:isubscribe
2019/08/26 全球购物
牵手50香港:专为黄金岁月的单身人士而设的交友网站
2020/08/14 全球购物
网络工程师的自我评价
2013/10/02 职场文书
2014年安全生产责任书
2014/07/22 职场文书
python爬虫selenium模块详解
2021/03/30 Python
Python可变与不可变数据和深拷贝与浅拷贝
2022/04/06 Python
win10重装系统后上不了网怎么办 win10重装系统网络故障的解决办法
2022/07/23 数码科技