Angularjs $http 拦截器 - 无法生成对 requestError 的调用

dew*_*ewd 4 javascript angularjs angular-http-interceptors

我使用$http拦截器来捕获 ajax 提交后的所有事件。由于某种原因,我无法抛出requestError. 我已经设置了一个测试应用程序来尝试调用requestError,但到目前为止我只能获取多个responseErrors.

来自angularjs文档:

requestError:当前一个拦截器抛出错误或通过拒绝解决时,拦截器被调用。

这是我的测试代码。

        .factory('httpInterceptor',['$q',function(q){

            var interceptor = {};

            var uniqueId = function uniqueId() {
                return new Date().getTime().toString(16) + '.' + (Math.round(Math.random() * 100000)).toString(16);
            };

            interceptor.request = function(config){
                config.id = uniqueId();
                console.log('request ',config.id,config);
                return config;
            };

            interceptor.response = function(response){
                console.log('response',response);
                return response;                    
            };

            interceptor.requestError = function(config){
                console.log('requestError ',config.id,config);
                return q.reject(config);
            };

            interceptor.responseError = function(response){
                console.log('responseError ',response.config.id,response);
                return q.reject(response);                    
            };

            return interceptor;

        }])

        .config(['$httpProvider',function($httpProvider) {
            $httpProvider.interceptors.push('httpInterceptor');
        }])

        .controller('MainCtrl',['$http',function($http){

            var mainCtrl = this;

            mainCtrl.method = null;
            mainCtrl.url = null;

            var testHttp = function testHttp() {

                $http({method:mainCtrl.method,url:mainCtrl.url}).then(
                        (response)=>{console.log('ok',response);},
                        (response)=>{console.log('reject',response);}
                );
            };

            //api
            mainCtrl.testHttp = testHttp;

        }])
Run Code Online (Sandbox Code Playgroud)

我尝试了多种创建 http 错误的方法,但每次都只responseError被调用。我尝试过的事情:

  • 让服务器为每个请求返回不同类型的错误,例如400500
  • 将服务器设置为sleep随机时间,以使稍后的请求在较早的请求之前响应错误。相同的资源,相同的服务器响应。
  • 404通过请求不存在的资源来生成错误。
  • 断开与互联网的连接 ( responseError -1)。

类似问题

1)这个问题似乎有了答案: 拦截HTTP请求和响应时,何时调用函数request、requestError、response、responseError?

关键段落是:

关键点是上述任何方法都可以返回“正常”对象/原语或将解析为适当值的承诺。在后一种情况下,队列中的下一个拦截器将等待,直到返回的 Promise 被解决或拒绝。

但我认为我正在按照它的规定去做,即sleep服务器随机但没有运气。我的请求发生reponseErrors故障,即服务器响应后。

2)大约1年前有人问过类似的问题:Angular and Jasmine: How to test requestError /rejection in HTTP拦截器?

不幸的是,它只提供了解释interceptors。它没有回答我的问题。

我已经在ChromeFirefox中进行了测试。我希望你能理解,我已经尽力找到解决方案,但目前还没有找到解决方案。

Est*_*ask 5

发生这种情况是因为请求在任何时候都没有被拒绝。它应该这样使用:

app.factory('interceptor1', ['$q', function ($q) {
  return {
    request: function (config) {
      console.log('request', config);
      if (config.url === 'restricted')
        return $q.reject({ error: 'restricted', config: config });
    }
  };
}]);

app.factory('interceptor2', ['$q', function ($q) {
  return {
    requestError: function (rejection) {
      console.log('requestError', rejection);      
      if (rejection.error === 'restricted')
        return angular.extend(rejection.config, { url: 'allowed' });

      return $q.reject(rejection);
    }
  };
}]);

app.config(['$httpProvider',function($httpProvider) {
  $httpProvider.interceptors.push('interceptor1');
  $httpProvider.interceptors.push('interceptor2');
}]);
Run Code Online (Sandbox Code Playgroud)

请注意,拦截器应该在堆栈中工作(从请求transform*中的钩子开始$http),因此请求不能在单个拦截器中被拒绝和恢复。