开发者社区> 炉火纯青> 正文

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

简介: $httpAngularJS 的 $http 服务允许我们通过发送 HTTP 请求方式与后台进行通信。在某些情况下,我们希望可以俘获所有的请求,并且在将其发送到服务端之前进行操作。还有一些情况是,我们希望俘获响应,并且在完成完成调用之前处理它。
+关注继续查看

$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');
}]);

拦截器允许你:

  • 通过实现 request 方法拦截请求: 该方法会在 $http 发送请求道后台之前执行,因此你可以修改配置或做其他的操作。该方法接收请求配置对象(request configuration object)作为参数,然后必须返回配置对象或者 promise 。如果返回无效的配置对象或者 promise 则会被拒绝,导致 $http 调用失败。

  • 通过实现 response 方法拦截响应: 该方法会在 $http 接收到从后台过来的响应之后执行,因此你可以修改响应或做其他操作。该方法接收响应对象(response object)作为参数,然后必须返回响应对象或者 promise。响应对象包括了请求配置(request configuration),头(headers),状态(status)和从后台过来的数据(data)。如果返回无效的响应对象或者 promise 会被拒绝,导致 $http 调用失败。

  • 通过实现 requestError 方法拦截请求异常: 有时候一个请求发送失败或者被拦截器拒绝了。请求异常拦截器会俘获那些被上一个请求拦截器中断的请求。它可以用来恢复请求或者有时可以用来撤销请求之前所做的配置,比如说关闭进度条,激活按钮和输入框什么之类的。

  • 通过实现 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);

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
HTTP 和 HTTPS(请求响应报文格式 + 请求方法 + 响应状态码 + HTTPS 加密流程 + Cookie 和 Session)
1. HTTP 是什么 2. HTTP 请求报文和响应报文的格式 1)请求报文格式 2)响应报文格式 3)报文中空行的作用 3. HTTP 的长连接和短连接 4. URL 1)在浏览器中输入 www.baidu.com 后执行的全部过程 5. HTTP 常用的请求方法 6. GET 和 POST 的区别 7. HTTP 常见的响应状态码 8. HTTPS 是什么 1)SSL 协议 9. HTTPS 怎么进行 “加密” 1)对称加密 2)非对称加密 3)CA 证书 4)HTTPS 加密的完整流程 10. HTTPS 的优缺点 11. HTTPS 和 HTTP 的区别
39 0
Angular 里 HTTP 请求和响应结构的拦截器(interceptors)在 SAP Spartacus 中的应用
Angular 里 HTTP 请求和响应结构的拦截器(interceptors)在 SAP Spartacus 中的应用
12 0
HTTP 请求和响应为什么会被分成多个数据包进行传输?底层原理是什么?
HTTP 请求和响应为什么会被分成多个数据包进行传输?底层原理是什么?
77 0
HTTP 请求或响应是干什么的?底层原理是什么?
HTTP 请求或响应是干什么的?底层原理是什么?
30 0
HTTP响应消息是干什么的?底层原理是什么?
HTTP响应消息是干什么的?底层原理是什么?
53 0
关于 HTTP 响应状态码你需要知道的一切
关于 HTTP 响应状态码你需要知道的一切
80 0
Tomcat 无法及时响应,http请求一直pending状态
Tomcat 无法及时响应,http请求一直pending状态
107 0
收到服务器401响应的处理(HTTP或SIP)
收到服务器401响应的处理(HTTP或SIP)
203 0
获取网页数据 Qt 从客户端发起http响应
获取网页数据 Qt 从客户端发起http响应
61 0
HTTP协议:响应消息和 Response对象和ServletContext对象
HTTP协议:响应消息和 Response对象和ServletContext对象
68 0
+关注
炉火纯青
pangguoming.com
文章
问答
视频
文章排行榜
最热
最新
相关电子书
更多
CDN助力企业网站进入HTTPS时代
立即下载
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载