我正在開發一個Angular webapp,它使用API來獲取一些數據。 要獲得這些數據,我必須發送一個智威湯遜。 我創建,爲了調用一個PHP文件,以獲得令牌服務:如何在AngularJS中刷新過期的jwt令牌
(function() {
'use strict';
angular
.module('MyApp')
.factory('TokenService', Service);
function Service($http, $localStorage) {
var service = {};
service.getToken = getToken;
return service;
function getToken() {
return $http.post('gettoken.php');
}
}})();
而我做的是在.RUN塊我把它和存儲接收的令牌:
function run($rootScope, $http, $location, $localStorage, TokenService) {
TokenService.getToken().then(function(response) {
$localStorage.token = response.data.token;
});
console.log('token: ' + $localStorage.token);
$http.defaults.headers.common.Authorization = 'Bearer ' + $localStorage.token;
}})();
每過幾分鐘,令牌就會過期,因此我必須請求另一個令牌,以便用戶可以繼續與API進行交互。
爲了解決這個問題,我的第一個方法是使用.config塊攔截401錯誤(令牌過期)並要求另一個令牌,但這是不可能的,因爲據我所知,不可能注入服務的.config塊:
function config2($httpProvider) {
$httpProvider.interceptors.push(function ($q, $rootScope) {
return {
'response': function (response) {
//Will only be called for HTTP up to 300
console.log(response);
return response;
},
'responseError': function (rejection) {
if(rejection.status === 401) {
var deferred = $q.defer();
TokenService.getToken(function() {
retryHttpRequest(response.config, deferred);
});
return deferred.promise;
} else {
return response;
}
function retryHttpRequest(config, deferred){
function successCallback(response){
deferred.resolve(response);
}
function errorCallback(response){
deferred.reject(response);
}
var $http = $injector.get('$http');
$http(config).then(successCallback, errorCallback);
}
}
};
});
}
事實上,當我執行的web應用程序,它說,TokenService沒有定義,如果我注入TokenService,顯然它創建了一個圓圈扶養:
angular.js:66 Uncaught Error: [$injector:cdep] Circular dependency found: $http <- TokenService <- $http <- $templateRequest <- $route
http://errors.angularjs.org/1.6.4/$injector/cdep?p0=%24http%20%3C-%20TokenService%20%3C-%20%24http%20%3C-%20%24templateRequest%20%3C-%20%24route
at angular.js:66
at getService (angular.js:4936)
at injectionArgs (angular.js:4969)
at Object.invoke (angular.js:4995)
at Object.enforcedReturnValue [as $get] (angular.js:4836)
at Object.invoke (angular.js:5003)
at angular.js:4795
at getService (angular.js:4944)
at injectionArgs (angular.js:4969)
at Object.invoke (angular.js:4995)
這是一個非常愚蠢的情況,但我花了整整一天試圖fi尋找最佳解決方案。 一旦攔截器檢測到401 responseError,我試圖簡單地重新加載頁面,但這不是最佳的,因爲用戶看到網絡刷新,並且他丟失了爲請求插入的所有數據。
如果有的話,你不得不處理這類問題,可以爲了解決它共享任何方式這將是巨大的。
非常感謝您的幫助。 我應用了你說的。現在的問題是當我在ResponseError中調用getToken時:它返回新的令牌,但它不適用於當前的401請求,所以我收到新的令牌,但對API的請求仍然失敗。 我正在閱讀你的解決方案在GitHub上,我希望我可以用該代碼解決它。 非常感謝! – Hmorv
我終於用你的工廠作爲例子調整了我的代碼。它的作品相當不錯!謝謝! – Hmorv