在angularjs拦截器中停止请求

时间:2014-08-24 15:53:57

标签: angularjs angularjs-service angular-promise

如何在Angularjs拦截器中停止请求。

有没有办法做到这一点?

我尝试使用promises并发送拒绝而不是解决!

.factory('connectionInterceptor', ['$q', '$timeout',
   function($q, $timeout) {
    var connectionInterceptor = {
        request: function(config) {
            var q = $q.defer();
            $timeout(function() {
                q.reject();
            }, 2000)
            return q.promise;
            // return config;
        }
    }
    return connectionInterceptor;
  }
])
.config(function($httpProvider) {
   $httpProvider.interceptors.push('connectionInterceptor');
});

5 个答案:

答案 0 :(得分:7)

$ http服务有一个选项 超时来完成这项工作。 你可以这样做:

angular.module('myApp')
    .factory('httpInterceptor', ['$q', '$location',function ($q, $location) {
        var canceller = $q.defer();
        return {
            'request': function(config) {
                // promise that should abort the request when resolved.
                config.timeout = canceller.promise;
                return config;
            },
            'response': function(response) {
                return response;
            },
            'responseError': function(rejection) {
                if (rejection.status === 401) {
                    canceller.resolve('Unauthorized'); 
                    $location.url('/user/signin');
                }
                if (rejection.status === 403) {
                    canceller.resolve('Forbidden');  
                    $location.url('/');
                }
                return $q.reject(rejection);
            }

        };
    }
    ])
    //Http Intercpetor to check auth failures for xhr requests
   .config(['$httpProvider',function($httpProvider) {
        $httpProvider.interceptors.push('httpInterceptor');
    }]);

答案 1 :(得分:5)

我最终绕过带有以下角度拦截器的角度XHR调用:

function HttpSessionExpiredInterceptor(sessionService) {
    return {
        request: function(config) {
            if (sessionService.hasExpired()) {
                /* Avoid any other XHR call. Trick angular into thinking it's a GET request.
                 * This way the caching mechanism can kick in and bypass the XHR call.
                 * We return an empty response because, at this point, we do not care about the
                 * behaviour of the app. */
                if (_.startsWith(config.url, '/your-app-base-path/')) {
                    config.method = 'GET';
                    config.cache = {
                        get: function() {
                            return null;
                        }
                    };
                }
            }

            return config;
        }
    };
}

这样,任何请求,POST,PUT,......都转换为GET,以便缓存机制可以 角度使用。此时,您可以在会话时使用自己的缓存机制 到期了,我不再关心什么回来。

答案 2 :(得分:1)

一般情况下不确定是否可行。但是您可以使用"取消器"。

启动$ http请求

以下是this answer的示例:

var canceler = $q.defer();
$http.get('/someUrl', {timeout: canceler.promise}).success(successCallback);
// later...
canceler.resolve();  // Aborts the $http request if it isn't finished.

因此,如果您可以控制启动请求的方式,那么这可能是一个选项。

答案 3 :(得分:0)

我最后还是返回了一个空对象

'request': function request(config) {
    if(shouldCancelThisRequest){  
        return {};
    }
    return config;
}

答案 4 :(得分:0)

以下是对我有用的方法,特别是用于停止传出请求和模拟数据的目的:


app
  .factory("connectionInterceptor", [
    "$q",
    function ($q) {
      return {
        request: function (config) {
          // you can intercept a url here with (config.url == 'https://etc...') or regex or use other conditions
          if ("conditions met") {
            config.method = "GET";
            // this is simulating a cache object, or alternatively, you can use a real cache object and pre-register key-value pairs,
            // you can then remove the if block above and rely on the cache (but your cache key has to be the exact url string with parameters)
            config.cache = {
              get: function (key) {
                // because of how angularjs $http works, especially older versions, you need a wrapping array to get the data
                // back properly to your methods (if your result data happens to be an array). Otherwise, if the result data is an object
                // you can pass back that object here without any return codes, status, or headers.
                return [200, mockDataResults, {}, "OK"];
              },
            };
          }
          return config;
        },
      };
    },
  ])
  .config(function ($httpProvider) {
    $httpProvider.interceptors.push("connectionInterceptor");
  });

如果你试图模拟一个结果

[42, 122, 466]

您需要发送一个带有一些 http 参数的数组,不幸的是,它正是 ng sendReq() 函数的编写方式。 (请参阅 https://github.com/angular/angular.js/blob/e41f018959934bfbf982ba996cd654b1fce88d43/src/ng/http.js#L1414 的第 1414 行或下面的代码段)

        // from AngularJS http.js

        // serving from cache
        if (isArray(cachedResp)) {
          resolvePromise(cachedResp[1], cachedResp[0], shallowCopy(cachedResp[2]), cachedResp[3], cachedResp[4]);
        } else {
          resolvePromise(cachedResp, 200, {}, 'OK', 'complete');
        }