詳解為Angular.js內置$http服務添加攔截器的方法
前言
在Angular框架中,創(chuàng)建團隊為使用者進行了Ajax請求的封裝,并通過$http服務暴露出相關的接口.Angular在其官方文檔中指出, $http服務底層針對Web常見的安全攻擊做出了相應的對策,也就是說使用$http服務封裝的Ajax為使用者提供了更為安全的保障.作為一個框架,保證框架的可用性,適配性是很有必要的. Angular在設計,實現(xiàn)中也體現(xiàn)出來了這樣的良好風格.我們通常在使用Ajax時,有時候希望我們能夠在請求發(fā)起前或接收到請求后做一些相應的處理工作,比如:在請求發(fā)起前,在請求頭中添加一下報文段.在請求返回時對一請求處理狀態(tài)做一些管理,如統(tǒng)一處理404狀態(tài)等等.Angular的$http服務在設計實現(xiàn)時充分考慮到了上述的情況.接下來,我們一起來學習和了解一下如何為$http服務添加攔截器,以及如何在我們自己實現(xiàn)的服務中實現(xiàn)類似的攔截器機制.
什么是攔截器–What are Interceptors?
Interceptor(攔截器)在服務端框架中屬于一種比較常見的機制,如spring,Struts2等Java框架中攔截器屬于基本配置項.攔截器提供了一種機制可以使開發(fā)者可以定義在一個action(動作)執(zhí)行的前后執(zhí)行的代碼,這些代碼可以是在一個action執(zhí)行前阻止其執(zhí)行的代碼,也可以是修改目標動作某些行為的代碼.(在AOP(Aspect-Oriented Programming)中攔截器用于在某個方法或字段被訪問之前,進行攔截然后在之前或之后加入某些操作。在Spring框架中比較常見)
$http服務中的攔截器
查看API或是源碼我們可以發(fā)現(xiàn),Angular的實現(xiàn)中通過 httpProvider提供了一個名為interceptors的數(shù)組.這個數(shù)組接受攔截器服務注冊,通過過程次的注冊最終會形成攔截器鏈.這樣每次在調用http服務的時候,angular都會通過我們定義的攔截點(切面)進行相應的Ajax動作修改.理論就不多說了,下面開始進入實戰(zhàn):
Angular中如何聲明一個攔截器
// Interceptor declaration
module.factory('httpInterceptor', ['$log', function($log) {
$log.debug('$log is here to show you that this is a regular factory with injection');
return {
// do something
};
}]);
如何將聲明的攔截器注冊到$http服務中
// Add the interceptor to $httpProvider.interceptors
module.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('httpInterceptor');
}]);
通過上面的簡單兩個步驟,我們基本就完成了http服務的攔截器編寫與添加.但是上面的代碼片段并不能實際使用,要想真正的實現(xiàn)攔截操作,我們還需要遵循h(huán)ttp服務暴露出來的可以進行攔截的點進行相關的代碼編寫.
$httpProvider暴露了那些可以攔截的點?
- request : request方法可以實現(xiàn)攔截請求: 該方法會在 http發(fā)送請求到服務器之前執(zhí)行,因此我們可以在該方法的視線中修改配置或做其他的操作。該方法接收請求配置對象(requestconfigurationobject)作為參數(shù),然后必須返回配置對象或者promise。如果返回無效的配置對象或者promise則會被拒絕,導致http 調用失敗。
- response : response方法可以實現(xiàn)攔截響應: 該方法會在 http接收到從服務器過來的響應之后執(zhí)行,因此我們可以修改響應報文或做其他操作。該方法接收響應對象(responseobject)作為參數(shù),然后必須返回響應對象或者promise。響應對象包括了請求配置(requestconfiguration),頭(headers),狀態(tài)(status)和從后臺過來的數(shù)據(data)。如果返回無效的響應對象或者promise會被拒絕,導致http 調用失敗。
- requestError : requestError方法可以實現(xiàn)攔截請求異常: 有時候一個請求發(fā)送失敗或者被攔截器拒絕了。請求異常攔截器會俘獲那些被上一個請求攔截器中斷的請求。它可以用來恢復請求或者有時可以用來撤銷請求之前所做的配置,比如說關閉進度條,激活按鈕和輸入框什么之類的。
- responseError : responseError方法可以實現(xiàn)攔截響應異常: 有時候我們后臺調用失敗了。也有可能它被一個請求攔截器拒絕了,或者被上一個響應攔截器中斷了。在這種情況下,響應異常攔截器可以幫助我們恢復后臺調用。
對于上面暴露出來的接口使用也是異常的簡單的,我們可以像聲明一個簡單的服務一樣聲明一個$http服務的攔截器,并交由angular的注入機制去使用我們配置的攔截器.
// 如同聲明一個Angular服務一樣聲明一個攔截器
module.factory('sessionInjector', ['authService', function (authService){
return {
request: function (config){
if (!authService.isAnonymus) {
config.headers['x-session-token'] = authService.token;
}
return config;
}
};
}]);
// 然后將我們聲明的攔截器添加到$httpProvider的攔截器鏈中,之后的服務注入Angular會負責幫我們完善
module.config(['$httpProvider', function ($httpProvider){
$httpProvider.interceptors.push('sessionInjector');
}]);
$http服務攔截器的異步支持
部分場景下,我們希望在攔截器中能夠執(zhí)行一些異步操作.然后依據不同的處理結果進行不同的攔截操作,AngularJS在設計的時候也很好的支持了這一特性.AngularJS允許我們在攔截的方法中,我們可以返回一個promise對象.如在http服務中,我們如果返回一個promise對象時,http服務將會延遲發(fā)起網絡請求或是延遲響應請求結果.
module.factory('myInterceptor', ['$q', 'someAsyncService', function($q, someAsyncService) {
var requestInterceptor = {
request: function(config) {
var deferred = $q.defer();
someAsyncService.doAsyncOperation().then(function() {
// Asynchronous operation succeeded, modify config accordingly
...
deferred.resolve(config);
}, function() {
// Asynchronous operation failed, modify config accordingly
...
deferred.resolve(config);
});
return deferred.promise;
},
response: function(response) {
var deferred = $q.defer();
someAsyncService.doAsyncOperation().then(function() {
// Asynchronous operation succeeded, modify response accordingly
...
deferred.resolve(response);
}, function() {
// Asynchronous operation failed, modify response accordingly
...
deferred.resolve(response);
});
return deferred.promise;
}
};
return requestInterceptor;
}]);
上面的例子中,在請求發(fā)起時,如果對應的deferred被拒絕,http請求則會失敗(如果進行抓包分析的話,你會發(fā)現(xiàn)http請求并沒有發(fā)起).在請求進行響應時,如果deferred被拒絕,則請求也會失敗.(抓包分析,網絡請求是有返回的).
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。
相關文章
Angular外部使用js調用Angular控制器中的函數(shù)方法或變量用法示例
這篇文章主要介紹了Angular外部使用js調用Angular控制器中的函數(shù)方法或變量用法,結合實例形式分析了Angular基于外部JS調用控制器中方法與變量的具體實現(xiàn)步驟與相關技巧,需要的朋友可以參考下2016-08-08

