angular - headers - Tiempo de espera de solicitud predeterminado y específico
httpclient angular 6 (3)
Parece que sin extender las clases
HttpClientModule
, las únicas formas esperadas para que los interceptores se comuniquen con las solicitudes respectivas son
params
y objetos de
headers
.
Dado que el valor de tiempo de espera es escalar, se puede proporcionar de forma segura como un encabezado personalizado al interceptor, donde se puede decidir si el tiempo de espera predeterminado o específico se debe aplicar a través del operador de
timeout
RxJS:
import { Inject, Injectable, InjectionToken } from ''@angular/core'';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from ''@angular/common/http'';
import { Observable } from ''rxjs'';
import { timeout } from ''rxjs/operators'';
export const DEFAULT_TIMEOUT = new InjectionToken<number>(''defaultTimeout'');
@Injectable()
export class TimeoutInterceptor implements HttpInterceptor {
constructor(@Inject(DEFAULT_TIMEOUT) protected defaultTimeout: number) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const timeoutValue = Number(req.headers.get(''timeout'')) || this.defaultTimeout;
return next.handle(req).pipe(timeout(timeoutValue));
}
}
Esto se puede configurar en el módulo de su aplicación como:
...
providers: [
[{ provide: HTTP_INTERCEPTORS, useClass: TimeoutInterceptor, multi: true }],
[{ provide: DEFAULT_TIMEOUT, useValue: 30000 }]
],
...
La solicitud se realiza con un encabezado de
timeout
personalizado
http.get(..., { headers: new HttpHeaders({ timeout: `${20000}` }) });
Como se supone que los encabezados son cadenas, el valor de tiempo de espera debe convertirse primero en una cadena.
Aquí hay una demostración .
Los créditos van a @RahulSingh y @ Jota.Toledo por sugerir la idea de usar interceptores con
timeout
.
Por lo general, es deseable tener un tiempo de espera predeterminado (por ejemplo, 30 segundos) que se aplicará a todas las solicitudes y se puede anular para solicitudes más largas en particular (por ejemplo, 600 segundos).
No hay una buena manera de especificar el tiempo de espera predeterminado en el servicio
Http
, que yo sepa.
¿Cuál es la forma de abordar esto en el servicio
HttpClient
?
¿Cómo definir un tiempo de espera predeterminado para todas las solicitudes salientes, que se puede anular para las específicas?
Puede crear un interceptor global con el valor de tiempo de espera base de la siguiente manera:
import { Injectable } from ''@angular/core'';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from ''@angular/common/http'';
@Injectable()
export class AngularInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).timeout(30000, Observable.throw("Request timed out"));
// 30000 (30s) would be the global default for example
}
}
Luego, debe registrar este inyectable en la matriz de proveedores de su módulo raíz.
La parte difícil sería anular el tiempo predeterminado (aumentar / disminuir) para solicitudes específicas. Por el momento no sé cómo resolver esto.
Usando el nuevo HttpClient puedes probar algo como esto
@Injectable()
export class AngularInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).timeout(5000).do(event => {}, err => { // timeout of 5000 ms
if(err instanceof HttpErrorResponse){
console.log("Error Caught By Interceptor");
//Observable.throw(err);
}
});
}
}
Agregar un tiempo de espera al
next.handle(req)
que se pasa.
Registrandolo en AppModule como
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [
[ { provide: HTTP_INTERCEPTORS, useClass:
AngularInterceptor, multi: true } ]
],
bootstrap: [AppComponent]
})
export class AppModule {
}