AngularJS拦截器永远不会捕获401错误

时间:2014-09-08 18:18:38

标签: javascript angularjs cordova angularjs-service ionic-framework

我使用Angular v1.2.20和Ionic Framework。我已经看过许多关于如何通过使用拦截器并将其推入$httpProvider.interceptors数组来处理来自服务器的401错误的文章和帖子。

出于某种原因,我的拦截器中的repsonseError函数永远不会捕获401响应。我期待拒绝的承诺永远不会拒绝,我的应用程序似乎挂起(loading:hide从下面永远不会被调用)。我可以从我的Web调试代理中看到401肯定是从服务器返回的。

我的拦截器:

.factory('interceptorService', function($rootScope, $q, Session, AuthorizationHeader) {
  var interceptorService = {
    request: function(config) {
      $rootScope.$broadcast('loading:show');
      config.headers['Authentication-Key'] = Session.key();
      config.headers['Authentication-Timestamp'] = (new Date().toJSON());
      config.headers['Authentication-Account'] = Session.accountName();
      if(typeof config.headers['Authorization'] === 'undefined') {
        config.headers['Authorization'] = 'Custom-HMAC-SHA512 ' + AuthorizationHeader.buildHashed(config, Session.key());
      }
      return config || $q.when(config);
    },

    response: function(response) {
      if(response.status === 401) {
        console.log('401');
      }
      $rootScope.$broadcast('loading:hide');
      return response || $q.when(response);
    },

    requestError: function(config) {
      $rootScope.$broadcast('loading:hide');
      return $q.reject(config);
    },

    responseError: function(response) {
      console.log('response error');
      $rootScope.$broadcast('loading:hide');
      return $q.reject(response);
    }
  };

  return interceptorService;
})

我可以确认拦截器正在工作,当我从服务器返回403时,我可以看到“#response”错误消息'在我的控制台日志中。另请注意,无论使用何种HTTP动词,都会发生这种情况。它发生在HEAD调用和DELETE调用上。

非常感谢任何帮助。

##编辑

看来这个问题是由于cordova / phonegap无法处理401响应中的www-authenticate标题引用in this blog post

如果有人对如何最好地处理这个问题有任何想法,我会全力以赴。

1 个答案:

答案 0 :(得分:1)

只需从响应中删除WWW-Authenticate标头,然后再返回到您的应用。这就是为我解决的问题。

handle 401 unauthorized error on windows Phone with Phonegap

编辑:我的工作中使用的实现是在我们的F5(负载均衡器)上完成的,因为那是我们的基本身份验证发生的地方。

这是我掀起的东西,尚未经过测试。您可以将它放在Global.asax.cs文件中的Application_EndRequest方法中:

    if (context.Response.Headers.Contains("WWW-Authenticate"))
        context.Response.Headers.Remove("WWW-Authenticate");