$httpAngularJS 的 $http 服務允許我們通過發(fā)送 HTTP 請求方式與后臺進行通信。在某些情況下,我們希望可以俘獲所有的請求,并且在將其發(fā)送到服務端之前進行操作。還有一些情況是,我們希望俘獲響應,并且在完成完成調用之前處理它。一個很好例子就是處理全局 http 異常。攔截器(Interceptors)應運而生。本文將介紹 AngularJS 的攔截器,并且給幾個有用的例子。
什么是攔截器?
$httpProvider 中有一個 interceptors 數(shù)組,而所謂攔截器只是一個簡單的注冊到了該數(shù)組中的常規(guī)服務工廠。下面的例子告訴你怎么創(chuàng)建一個攔截器:
<!-- 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 數(shù)組:
<!-- lang: js -->module.config(['$httpProvider', function($httpProvider) { $httpProvider.interceptors.push('myInterceptor');}]);攔截器允許你:
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'});//跳轉到登錄界面 }});另外還有用戶已經(jīng)登錄,但是登錄超時了,還有就是增加后臺接口的判斷來增強安全性。不能完全依靠本地邏輯
我們在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中做更多的細節(jié)處理
// 如果用戶已經(jīng)登錄了,則立即跳轉到一個默認主頁上去,無需再登錄if($rootScope.user.token){ $state.go($rootScope.defaultPage); return;}另外在登錄成功回調后還可以跳轉到上一次界面,也就是上面記錄的from
var from = $stateParams["from"];$state.go(from && from != "login" ? from : $rootScope.defaultPage);
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網(wǎng)。
新聞熱點
疑難解答