Angle 4.3 HttpClient: réponse D'interception
Dans la documentation sur le nouveau HttpClientModule
inclus dans la nouvelle version Angulaire 4.3, le mécanisme d'intercepter les demandes est très bien expliqué. Il est également fait mention du mécanisme d'interception de la réponse, mais je ne trouve rien à ce sujet.
quelqu'un aurait-il une idée sur la façon d'intercepter une réponse afin de modifier le corps du message avant de l'envoyer au service?
Merci.
4 réponses
j'ai récemment fait un HttpInterceptor
afin de résoudre les références cycliques dans certains JSON du côté client, remplaçant essentiellement n'importe quel objet par un $ref
propriété avec l'objet dans le JSON qui a une correspondance $id
propriété. (C'est la sortie que vous obtenez si Json.Net est configuré avec PreserveReferencesHandling.Objects
et ReferenceLoopHandling.Ignore
).
les réponses ici m'ont aidé d'une certaine manière, mais aucune d'elles ne montre comment modifier le corps de la réponse, comme les besoins de L'OP. Pour ce faire, on a besoin de cloner l' de l'événement et de mettre à jour le corps, comme suit:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).map(event => {
if (event instanceof HttpResponse && shouldBeIntercepted(event)) {
event = event.clone({ body: resolveReferences(event.body) })
}
return event;
});
}
tout événement qui ne devrait pas être modifié est simplement transmis au gestionnaire suivant.
je suppose que vous pouvez utiliser do
@federico-scamuzzi suggéré, ou vous pouvez utiliser map
et catch
comme:
import { Injectable } from '@angular/core';
import {
HttpErrorResponse,
HttpEvent,
HttpHandler,
HttpInterceptor,
HttpRequest,
HttpResponse
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.info('req.headers =', req.headers, ';');
return next.handle(req)
.map((event: HttpEvent<any>) => {
if (event instanceof HttpResponse && ~~(event.status / 100) > 3) {
console.info('HttpResponse::event =', event, ';');
} else console.info('event =', event, ';');
return event;
})
.catch((err: any, caught) => {
if (err instanceof HttpErrorResponse) {
if (err.status === 403) {
console.info('err.error =', err.error, ';');
}
return Observable.throw(err);
}
});
}
}
EDIT: @LalitKushwah s'interrogeait sur la redirection if(!loggedIn)
. J'utilise Gardes De La Route, plus précisément:
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot
} from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { AuthService } from '../../api/auth/auth.service';
import { AlertsService } from '../alerts/alerts.service';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private router: Router,
private alertsService: AlertsService) {}
canActivate(next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
if (AuthService.loggedIn()) return true;
const url: string = state.url;
this.alertsService.add(`Auth required to view ${url}`);
this.router
.navigate(['/auth'], { queryParams: { redirectUrl: url } })
.then(() => {});
return false;
}
}
Ensuite, je peux simplement ajouter que comme un argument de mon itinéraire:
{
path: 'dashboard', loadChildren:'app/dashboard/dashboard.module#DashboardModule',
canActivate: [AuthGuard]
}
avec la version 6 angulaire ils ont adapté RxJs 6.0 à cause de cela la plupart des solutions ci-dessus ne fonctionneront pas dans cette version particulière d'angular, c'est ainsi que vous modifiez correctement le contenu D'un Observable
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http';
import {Observable} from 'rxjs/internal/Observable';
import {Injectable} from '@angular/core';
import {tap} from 'rxjs/operators';
@Injectable()
export class ResponseInterceptor implements HttpInterceptor {
intercept(req: HttpRequest, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(tap((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
event = event.clone({body: this.modifyBody(event.body)});
}
return event;
}));
}
private modifyBody(body: any) {
/*
* write your logic to modify the body
* */
}
}
D'après ce que je peux comprendre (j'ai seulement fait l'interception pour request et injecter auth token) .. vous pouvez joindre un .n'() et tester si il est une reponse .. comme (comme le dit le doc):
import 'rxjs/add/operator/do';
export class TimingInterceptor implements HttpInterceptor {
constructor(private auth: AuthService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const started = Date.now();
return next
.handle(req)
.do(event => {
if (event instanceof HttpResponse) { //<-- HERE
const elapsed = Date.now() - started;
console.log(event} ms.`);
}
});
}
}