详解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 相关文章推荐
js实现一个省市区三级联动选择框代码分享
Mar 06 Javascript
JavaScript 实现鼠标拖动元素实例代码
Feb 24 Javascript
脚本合并提升javascript性能示例
Feb 24 Javascript
浅谈JavaScript中的分支结构
Jul 01 Javascript
AngularJS使用指令增强标准表单元素功能
Jul 01 Javascript
微信JS接口大全
Aug 25 Javascript
深入理解jQuery3.0的domManip函数
Sep 01 Javascript
详解js中Number()、parseInt()和parseFloat()的区别
Dec 20 Javascript
js实现从左向右滑动式轮播图效果
Jul 07 Javascript
vue-cli项目中使用公用的提示弹层tips或加载loading组件实例详解
May 28 Javascript
GOJS+VUE实现流程图效果
Dec 01 Javascript
jenkins自动构建发布vue项目的方法步骤
Jan 04 Vue.js
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
解析dedeCMS验证码的实现代码
2013/06/07 PHP
PHP中ID设置自增后不连续的原因分析及解决办法
2016/08/21 PHP
AJAX PHP无刷新form表单提交的简单实现(推荐)
2016/09/09 PHP
php探针使用原理和技巧讲解
2019/09/17 PHP
Laravel Eloquent ORM 多条件查询的例子
2019/10/10 PHP
Yii使用EasyWechat实现小程序获取用户的openID的方法
2020/04/29 PHP
JavaScript DOM学习第一章 W3C DOM简介
2010/02/19 Javascript
jquery 学习之二 属性 文本与值(text,val)
2010/11/25 Javascript
在VS2008中使用jQuery智能感应的方法
2010/12/30 Javascript
Extjs4 消息框去掉关闭按钮(类似Ext.Msg.alert)
2013/04/02 Javascript
jquery实现勾选复选框触发事件给input赋值
2015/02/01 Javascript
jquery实现增加删除行的方法
2015/02/03 Javascript
jQuery中dom元素上绑定的事件详解
2015/04/24 Javascript
jquery实现漫天雪花飞舞的圣诞祝福雪花效果代码分享
2015/08/20 Javascript
[原创]Bootstrap 中下拉菜单修改成鼠标悬停直接显示
2016/04/14 Javascript
Bootstrap每天必学之折叠(Collapse)插件
2016/04/25 Javascript
Javascript基础之数组的使用
2016/05/13 Javascript
vue中slot(插槽)的介绍与使用
2018/11/12 Javascript
使用JavaScript解析URL的方法示例
2019/03/01 Javascript
npm ci命令的基本使用方法
2020/09/20 Javascript
[00:57]林俊杰助阵DOTA2亚洲邀请赛
2015/01/28 DOTA
Python3基础教程之递归函数简单示例
2019/06/07 Python
Django的Modelforms用法简介
2019/07/27 Python
python gui开发——制作抖音无水印视频下载工具(附源码)
2021/02/07 Python
德国EGOIST网店:销售畅销的设计师品牌
2017/04/18 全球购物
新奥尔良珠宝:Mignon Faget
2020/11/23 全球购物
见习期自我鉴定
2014/01/31 职场文书
司机职责范本
2014/03/08 职场文书
初中班主任评语大全
2014/04/24 职场文书
工作批评与自我批评范文
2014/10/16 职场文书
2014年社区工作总结
2014/11/18 职场文书
2016年社区中秋节活动总结
2016/04/05 职场文书
2016年第十九届推普周活动总结
2016/04/06 职场文书
工作一年自我鉴定
2019/06/20 职场文书
浅谈Web Storage API的使用
2021/06/23 Javascript
Go语言基础切片的创建及初始化示例详解
2021/11/17 Golang