Angular 5 - 响应HttpInterceptor - 超时重试(504)

时间:2018-02-07 19:09:50

标签: angular observable interceptor

我尝试实现HttpInterceptor来重试超时请求。我实现了以下代码,但是错误不包含状态代码,因此它不起作用。

@Injectable()
export class RetryInterceptor implements HttpInterceptor {

    constructor() { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(req)
            .retryWhen(error => {
                return error
                    .flatMap((err) => {

                        if (err instanceof HttpErrorResponse && err.status === 504) { // timeout

                            return Observable.of(err.status).delay(5000);
                        }

                        return Observable.throw({ error: 'No retry' });
                    })
                    .take(1)
                    .concat(Observable.throw({ error: 'Sorry, there was an error (after 5 retries)' }));

            });
    }
}

错误对象具有以下对象(注意状态为0):

enter image description here

Devtools显示错误504: enter image description here

任何人都可以帮助我吗?

提前致谢!

----更新---- 经过深入分析后,我发现问题在于我有另一个拦截器,它将Auth标头添加到我的请求中。我创建了一个stackblitz示例来显示此问题:https://stackblitz.com/edit/angular-interceptors-azhwak 在上面的示例中,您可以检查错误代码始终为0(零),即使错误是504.如果您注释掉其他拦截器(I2),代码将按预期工作。

不确定我是否做错了或者我不应该有多个拦截器(有些更新请求,还有一些响应)?

更新2

User @ AngularInDepth.com是对的,问题是没有提供CORS。管理以使其使用不同的服务。但是现在我面临着一个不同的问题,我想在第一次重试后才调用第二个拦截器(I2)。有办法吗?

请参阅更新后的示例:https://stackblitz.com/edit/angular-interceptors-ckbvsb

由于

1 个答案:

答案 0 :(得分:1)

问题在于服务https://httpstat.us/504本身。当您向请求添加自定义标头并因此XHR请求错误而不是发出请求时,它无法正确处理CORS。当XHR出错时,您的状态为0,因为没有请求。 Here is the plunker证明了这一点和代码:

request() {
    const url = 'https://httpstat.us/504';

    var xhr = new XMLHttpRequest();  
    xhr.open('GET', url);      

    // when commented out `onload` handler is executed, otherwise `onerror`    
    // xhr.setRequestHeader('any', 'any');

    xhr.onload = () => {console.log('loaded')};
    xhr.onerror = () => {console.log('errror')};

    xhr.send();
}