【问题标题】:Angular - Limit HTTP interceptor retriesAngular - 限制 HTTP 拦截器重试
【发布时间】:2015-11-13 16:41:23
【问题描述】:

我编写了一个拦截器,当响应错误时,如果本地存储中存在状态代码和访问令牌,则重试 HTTP 请求。

我写这篇文章主要是为了应对来自我们正在使用的 API 的神秘失败的响应(我无法控制),因为在某些情况下重试就足够了。有时 API 端点会无缘无故地失败,所以我想,由于我无法控制 API 的维护,所以我只能重试发送 HTTP 请求。

primesis.factory('httpResponseErrorInterceptor', function ($q, $injector) {
    return {
        'responseError': function (response) {
            if(response.status === 500 && localStorage.getItem('token')) {
                var $http = $injector.get('$http');
                return $http(response.config);
            }
            return $q.reject(response);
        }
    };
});

   $httpProvider.interceptors.push('httpResponseErrorInterceptor');

但是,在 API 中确实存在错误的情况下,这会导致拦截器无限重试。

我想要实现的是限制此拦截器的重试次数。我尝试在其中放置一个计数器,但似乎该计数器没有继续到下一个拦截器调用。

我一直在寻找可以解决此类情况的方法,但无济于事。有没有办法限制拦截器响应错误重试?

【问题讨论】:

    标签: angularjs angular-http-interceptors


    【解决方案1】:

    @csupnig 的答案如果你能想象它并为它编写一个实现就可以了,但我设法在同一个拦截器本身的范围内做到了:没有添加服务。

    我是这样做的:

    app.factory('httpResponseErrorInterceptor', function ($q, $injector) {
            return {
                responseError: function (response) {
                    if(response.status === 500 && localStorage.getItem('token')) {
                    var $http = $injector.get('$http');
    
                    if(response.config.Retries===undefined){
                        //do something on first error e.g, reporting
                        response.config.Retries=1;
                        return $http(response.config);
                    }else{
                        if(response.config.Retries!==2){
                            response.config.Retries = response.config.Retries +1;
                            return $http(response.config);
                        }
                        else{
                            response.config.Retries = undefined;
                            //do something on last retry
                            return $q.reject(response);
                        }
                    }
                }
                return $q.reject(response); // give up
            }
        };
    }); 
    

    这通过在响应配置​​本身上附加计数器来工作。

    我承认这可以使用一些重构,但你明白了。这适用于我的用例,我认为这很容易改变。

    【讨论】:

      【解决方案2】:

      计数器是正确的解决方案,但您必须将其放入服务中才能使其在下一次拦截器调用中存活。

      我将构建一个管理请求和重试映射的服务。

      【讨论】:

      • 这就是问题所在!我是否认为需要将该服务注入拦截器中?我是否必须为计数器创建访问器和修改器?我无法想象如何将计数器与它们各自的请求相关联。
      • 是的,您必须将服务注入拦截器,是的,您应该为计数器创建访问器和修改器。问题是您如何跟踪请求及其计数器。一种可能性是对 URL 和参数进行哈希处理,但这会导致类似的请求也具有相同的计数器。我建议在您发出请求的地方生成一个 uuid,并使用相同的 uuid 进行重试。一旦请求成功,您应该清除计数器。
      • 我现在开始变得更清楚了,但是我如何区分重试请求和新请求? (因为我会为新的 UUID 创建一个 UUID 并为重试但仍然失败的计数器添加。)
      猜你喜欢
      • 1970-01-01
      • 2021-04-23
      • 2023-03-13
      • 1970-01-01
      • 2017-11-07
      • 2018-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多