AngularJS拦截重试请求
AngularJS interceptor retry request
你好,我正在开发一个 Angular 应用程序,我在尝试重试在 http 拦截器中发出的最新请求时遇到了一些问题。
我有这个拦截器用于对每个请求进行身份验证验证,并且我在令牌过期的响应中也有它。问题是,当我的令牌过期时,我需要为它触发刷新令牌以获得新的访问权限,如果它成功,那么我会重试拦截的请求。
一切正常。但是...我有多个被拒绝的 401 呼叫,当我尝试登录时(您可以看到 console.log 消息)。似乎只有第一个被拒绝的调用才会触发刷新令牌请求。什么是最好的方法或可以使其发挥作用的方法?提早。
var _responseError = function (rejection) {
if (rejection.status === 401) {
var authService = $injector.get('authService');
var state = $injector.get('$state');
var http = $injector.get('$http');
var deferred = $q.defer();
if (rejection.data && rejection.data.ErrorCode == errorCodes.missingRole){
return $q.reject(rejection);
}
//var authData = localStorageService.get(authConstant.cookieName);
var authData = authService.getAuth();
if (authData) {
return authService.refreshToken().then(function (response) {
console.log("call is: ", rejection);
if (response.access_token){
//Todo: find a method to resend last request;
return http(rejection.config);
}
},
function (err) {
state.go('app.login');
return $q.reject(rejection);
});
}
authService.logOut();
state.go('app.login');
}
return $q.reject(rejection);
};
有类似的问题。我的代码有点不同,但思路是一样的,试试这个
var deferred = $q.defer();
authService.refreshToken().then(function () {
$http(errorResponse.config).then(deferred.resolve, deferred.reject);
}, function () {
authService.logOut().then(deferred.reject);
});
return deferred.promise;
我已经设法使用 http 缓冲区来存储所有未来被拒绝的后端调用来解决这个问题。
缓冲区代码在这里:
https://github.com/witoldsz/angular-http-auth/blob/master/src/http-auth-interceptor.js
我稍微修改了一下使其正常工作,这是修改后的版本:
angular.module('authModule').factory('httpBufferService', ['$injector', function($injector) {
/** Holds all the requests, so they can be re-requested in future. */
var buffer = [];
var doAction=false;
/** Service initialized later because of circular dependency problem. */
var $http;
function retryHttpRequest(config, deferred) {
function successCallback(response) {
deferred.resolve(response);
}
function errorCallback(response) {
deferred.reject(response);
}
$http = $http || $injector.get('$http');
$http(config).then(successCallback, errorCallback);
}
var bufferData = {
getItems:function (){
return buffer;
},
/**
* Appends HTTP request configuration object with deferred response attached to buffer.
*/
append: function(config, deferred) {
buffer.push({
config: config,
deferred: deferred
});
},
/**
* Abandon or reject (if reason provided) all the buffered requests.
*/
rejectAll: function(reason) {
if (reason) {
for (var i = 0; i < buffer.length; ++i) {
buffer[i].deferred.reject(reason);
}
}
buffer = [];
},
clean:function(){
buffer = [];
doAction = false;
},
/**
* Retries all the buffered requests clears the buffer.
*/
retryAll: function() {
if (!doAction){
doAction = true;
for (var i = 0; i < buffer.length; ++i) {
retryHttpRequest(buffer[i].config, buffer[i].deferred);
}
bufferData.clean();
}
}
};
return bufferData;
}]);
这是实现:
var authData = authService.getAuth();
httpBuffer.append(rejection.config,defer);
if (httpBuffer.getItems().length>1){
return defer.promise;
}
if (authData) {
return authService.refreshToken().then(function (response) {
if (response.access_token){
httpBuffer.retryAll();
return defer.promise;
}
},
function (err) {
httpBuffer.clean();
authService.logOut();
return $q.reject(rejection);
});
}
httpBuffer.clean();
你好,我正在开发一个 Angular 应用程序,我在尝试重试在 http 拦截器中发出的最新请求时遇到了一些问题。 我有这个拦截器用于对每个请求进行身份验证验证,并且我在令牌过期的响应中也有它。问题是,当我的令牌过期时,我需要为它触发刷新令牌以获得新的访问权限,如果它成功,那么我会重试拦截的请求。
一切正常。但是...我有多个被拒绝的 401 呼叫,当我尝试登录时(您可以看到 console.log 消息)。似乎只有第一个被拒绝的调用才会触发刷新令牌请求。什么是最好的方法或可以使其发挥作用的方法?提早。
var _responseError = function (rejection) {
if (rejection.status === 401) {
var authService = $injector.get('authService');
var state = $injector.get('$state');
var http = $injector.get('$http');
var deferred = $q.defer();
if (rejection.data && rejection.data.ErrorCode == errorCodes.missingRole){
return $q.reject(rejection);
}
//var authData = localStorageService.get(authConstant.cookieName);
var authData = authService.getAuth();
if (authData) {
return authService.refreshToken().then(function (response) {
console.log("call is: ", rejection);
if (response.access_token){
//Todo: find a method to resend last request;
return http(rejection.config);
}
},
function (err) {
state.go('app.login');
return $q.reject(rejection);
});
}
authService.logOut();
state.go('app.login');
}
return $q.reject(rejection);
};
有类似的问题。我的代码有点不同,但思路是一样的,试试这个
var deferred = $q.defer();
authService.refreshToken().then(function () {
$http(errorResponse.config).then(deferred.resolve, deferred.reject);
}, function () {
authService.logOut().then(deferred.reject);
});
return deferred.promise;
我已经设法使用 http 缓冲区来存储所有未来被拒绝的后端调用来解决这个问题。 缓冲区代码在这里: https://github.com/witoldsz/angular-http-auth/blob/master/src/http-auth-interceptor.js
我稍微修改了一下使其正常工作,这是修改后的版本:
angular.module('authModule').factory('httpBufferService', ['$injector', function($injector) {
/** Holds all the requests, so they can be re-requested in future. */
var buffer = [];
var doAction=false;
/** Service initialized later because of circular dependency problem. */
var $http;
function retryHttpRequest(config, deferred) {
function successCallback(response) {
deferred.resolve(response);
}
function errorCallback(response) {
deferred.reject(response);
}
$http = $http || $injector.get('$http');
$http(config).then(successCallback, errorCallback);
}
var bufferData = {
getItems:function (){
return buffer;
},
/**
* Appends HTTP request configuration object with deferred response attached to buffer.
*/
append: function(config, deferred) {
buffer.push({
config: config,
deferred: deferred
});
},
/**
* Abandon or reject (if reason provided) all the buffered requests.
*/
rejectAll: function(reason) {
if (reason) {
for (var i = 0; i < buffer.length; ++i) {
buffer[i].deferred.reject(reason);
}
}
buffer = [];
},
clean:function(){
buffer = [];
doAction = false;
},
/**
* Retries all the buffered requests clears the buffer.
*/
retryAll: function() {
if (!doAction){
doAction = true;
for (var i = 0; i < buffer.length; ++i) {
retryHttpRequest(buffer[i].config, buffer[i].deferred);
}
bufferData.clean();
}
}
};
return bufferData;
}]);
这是实现:
var authData = authService.getAuth();
httpBuffer.append(rejection.config,defer);
if (httpBuffer.getItems().length>1){
return defer.promise;
}
if (authData) {
return authService.refreshToken().then(function (response) {
if (response.access_token){
httpBuffer.retryAll();
return defer.promise;
}
},
function (err) {
httpBuffer.clean();
authService.logOut();
return $q.reject(rejection);
});
}
httpBuffer.clean();