详解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 相关文章推荐
xmlHTTP实例
Oct 24 Javascript
js常用代码段整理
Nov 30 Javascript
jQuery操作表格(table)的常用方法、技巧汇总
Apr 12 Javascript
仿淘宝TAB切换搜索框搜索切换的相关内容
Sep 21 Javascript
JavaScript字符串对象slice方法入门实例(用于字符串截取)
Oct 16 Javascript
javascript arguments使用示例
Dec 16 Javascript
js实现类似MSN提示的页面效果代码分享
Aug 24 Javascript
JS实现同一个网页布局滑动门和TAB选项卡实例
Sep 23 Javascript
Three.js利用orbit controls插件(轨道控制)控制模型交互动作详解
Sep 25 Javascript
vue 进阶之实现父子组件间的传值
Apr 26 Javascript
vue动态绑定style样式
Apr 20 Vue.js
js面向对象编程OOP及函数式编程FP区别
Jul 07 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
php5 non-thread-safe和thread-safe这两个版本的区别分析
2010/03/13 PHP
域名和cookie问题(域名后缀)
2012/10/10 PHP
php获取网卡的MAC地址支持WIN/LINUX系统
2014/04/30 PHP
PHP中使用file_get_contents post数据代码例子
2015/02/13 PHP
Smarty高级应用之缓存操作技巧分析
2016/05/14 PHP
php对接java现实加签验签的实例
2016/11/25 PHP
PHP 网站修改默认访问文件的nginx配置
2017/05/27 PHP
jquery 页面滚动到指定DIV实现代码
2013/09/25 Javascript
jquery选择器之内容过滤选择器详解
2014/01/27 Javascript
js完美实现@提到好友特效(兼容各大浏览器)
2015/03/16 Javascript
JavaScript实现复制或剪切内容到剪贴板功能的方法
2016/05/23 Javascript
使用jsonp实现跨域获取数据实例讲解
2016/12/25 Javascript
mui上拉加载功能实例详解
2017/04/13 Javascript
使用jQuery.Pin垂直滚动时固定导航
2017/05/24 jQuery
angular4 如何在全局设置路由跳转动画的方法
2017/08/30 Javascript
nodeJs实现基于连接池连接mysql的方法示例
2018/02/10 NodeJs
JavaScript实现创建自定义对象的常用方式总结
2018/07/09 Javascript
jQuery实现的鼠标拖动浮层功能示例【拖动div等任何标签】
2018/12/29 jQuery
Vue Components 数字键盘的实现
2019/09/18 Javascript
JavaScript实现拖拽盒子效果
2020/02/06 Javascript
Auto.JS实现抖音刷宝等刷视频app,自动点赞,自动滑屏,自动切换视频功能
2020/05/08 Javascript
Python基础练习之用户登录实现代码分享
2017/11/08 Python
关于python2 csv写入空白行的问题
2018/06/22 Python
Python实现定期检查源目录与备份目录的差异并进行备份功能示例
2019/02/27 Python
Python新手学习标准库模块命名
2020/05/29 Python
检测浏览器对HTML5和CSS3支持度的方法
2015/06/25 HTML / CSS
学生感冒英文请假条
2014/02/04 职场文书
毕业自我评价
2014/02/05 职场文书
军训自我鉴定200字
2014/02/13 职场文书
班长竞选演讲稿
2014/04/24 职场文书
2014年幼儿园教师工作总结
2014/11/08 职场文书
贫困生助学金感谢信
2015/01/21 职场文书
2015年幼儿园后勤工作总结
2015/04/25 职场文书
2019运动会广播加油稿汇总
2019/08/21 职场文书
教你快速构建一个基于nginx的web集群项目
2021/11/27 Servers
python通过新建环境安装tfx的问题
2022/05/20 Python