Angularjs 使用Angular.js拦截器捕获HTTP 401

Angularjs 使用Angular.js拦截器捕获HTTP 401,angularjs,authentication,Angularjs,Authentication,我想用Angular.js在单页web应用程序上实现身份验证。建议使用拦截器: $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) { return { // ... 'responseError': function(rejection) { // do something on error if (canRecover(rejection))

我想用Angular.js在单页web应用程序上实现身份验证。建议使用拦截器:

$provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
  return {

    // ...

    'responseError': function(rejection) {
      // do something on error
      if (canRecover(rejection)) {
        return responseOrNewPromise
      }
      return $q.reject(rejection);
    }
  };
});
问题是,当服务器发送401错误时,浏览器会立即停止,并显示“Unauthorized”消息或登录弹出窗口(当服务器发送身份验证HTTP头时),但Angular无法按照建议使用其拦截器捕获要处理的HTTP错误。我是不是误解了什么?我尝试了在web上找到的更多示例(,例如),但没有一个有效。

在应用程序配置块中:

var interceptor = ['$rootScope', '$q', "Base64", function(scope, $q, Base64) {
  function success(response) {
    return response;
  }

  function error(response) {
    var status = response.status;
    if (status == 401) {
      //AuthFactory.clearUser();
      window.location = "/account/login?redirectUrl=" + Base64.encode(document.URL);
      return;
    }
    // otherwise
    return $q.reject(response);
  }
  return function(promise) {
    return promise.then(success, error);
  }
}];

我不知道为什么,但401错误的响应进入成功函数

'responseError': function(rejection)
                {
                    // do something on error

                    if (rejection.status == 401)
                    {
                        $rootScope.signOut();
                    }

                    return $q.reject(rejection);
                },
                'response': function (response) {
                    // do something on error
                    if (response.status == 401) {
                        $rootScope.signOut();
                    };
                    return response || $q.when(response);
                }

AngularJS拦截器仅适用于使用$http服务进行的调用;如果导航到返回401的页面,AngularJS甚至不会运行。

对于AngularJS>1.3,请使用
$httpProvider.interceptors.push('myHttpInterceptor')


示例:1.3中1.3不再支持responseInterceptor,它的绑定方式如下:$httpProvider.interceptors.push('interceptor');在Angular 1.5上它对我不起作用。我必须使用下面的Igor S方法你知道吗?我在这里遇到了完全相同的问题,答案都不起作用,拦截器确实起作用,但异常仍然会在拦截器之前抛出。这很奇怪吗?我试了这么多东西,我还是抓不到401。你能用一个拦截器做到吗?(由于某种原因,它被翻译成了404)@windmaomao这取决于你所说的导航。满负荷的页面(window.location)确实不会触发拦截器。但是导航到应用程序中的另一个路由将被删除,因为路由模板是使用$http服务获取的。在这种情况下,您可以使用:.$on(“$locationChangeStart”,function(event,next,current){和.$on(“$locationChangeSuccess”,function(event,next,current){如果您向服务器发出$http请求并返回401,Angular与此无关,开发人员应该决定怎么做;在这个问题中,他可能希望将用户重定向到新路由,甚至可能删除双方的auth令牌。'responseError'非常有帮助:-)我还发现401最后出现在
response
中,而不是
responseError
。Angular 1.5.3.编辑:看起来可能是因为我使用的第三方库,
http auth interceptor
。尽管我已经指定该库应该忽略此特定请求,但它似乎仍然导致401无法通过管道
responseError
“responseError”是要做的事情。为了更好的衡量,请注意还有“requestError”。回答很好!这是一个通用的功能,一旦您未经授权,它将重定向到登录。最后,这很有效!!!我最初使用的是“response”而不是“responseError”这导致我的拦截器功能无法执行。
.service('authInterceptor', function($q) {
    var service = this;

    service.responseError = function(response) {
        if (response.status == 401){
            window.location = "/login";
        }
        return $q.reject(response);
    };
})
.config(['$httpProvider', function($httpProvider) {
    $httpProvider.interceptors.push('authInterceptor');
}])