几天前我刚开始使用 AngularJS,我的拦截器遇到了问题,它从服务器响应中拦截 401 状态。
当返回 401 并在该事件上触发重定向时,它会广播类型为“loginRequired”的消息。
问题是,如果我在未登录的情况下尝试访问受限页面,我会在重定向到登录页面之前看到页面闪烁片刻。我仍然是异步东西,承诺等方面的初学者。有人能指出我做错了什么吗?
这是我的拦截器。如您所见,它非常简单,但我将其精简以解释我的观点,并且在进一步开发之前尝试理解事物。
拦截器
var services = angular.module('services', []);
services.factory('myInterceptor', ['$q', '$rootScope',
function($q,$rootScope) {
var myInterceptor = {
'responseError': function(rejection) {
$rootScope.$broadcast('event:loginRequired');
return $q.reject(rejection);
}
};
return myInterceptor;
}
]);
我的拦截器的注入
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('myInterceptor');
}]);
受限页面的路由
.when('/restrictedPage', {
templateUrl: 'partials/restrictedPage.html',
controller: 'RestrictedPageController'
}).
受限页面控制器
controllers.controller('RestrictedPageController', function($scope) {
//Some times the alert pops up, sometimes not.
alert("Damn it I shouldn't be there");
});
$rootScope 事件观察器
$rootScope.$on('event:loginRequired', function() {
//Only redirect if we aren't on free access page
if ($location.path() == "/freeAccess")
return;
//else go to the login page
$location.path('/home').replace();
});
我的问题显然与我处理拦截器和 $q 的方式有关。我在github上找到了另一种创建拦截器的方式,但这不是官方文档使用的方式,所以我认为这可能是旧方式,在我看来它不如将它放在工厂中那么干净。他只是在他的模块的配置函数中定义了路由之后才放了这段代码。但是这段代码有效,我没有得到页面闪存。
我在 Github 上找到的另一种方法
var interceptor = ['$rootScope', '$q', '$log',
function(scope, $q, $log) {
function success(response) {
return response;
}
function error(response) {
var status = response.status;
if (status == 401) {
var deferred = $q.defer();
var req = {
config: response.config,
deferred: deferred
};
scope.$broadcast('event:loginRequired');
return deferred.promise;
}
// otherwise
return $q.reject(response);
}
return function(promise) {
return promise.then(success, error);
};
}
];
$httpProvider.responseInterceptors.push(interceptor);
但我的目标不仅仅是“让它发挥作用”,而且我讨厌“如果它没有坏就不要修复它”的口头禅。我想了解我的代码有什么问题。谢谢!