Website-Suche

typescript - Gibt es eine Möglichkeit, die Antwort in einem Angular 5 HttpInterceptor zu ändern?


Für meine Anwendung habe ich den folgenden HttpInterceptor erstellt. Gibt es eine Möglichkeit, von hier aus eine veränderte Version der Antwort an die Anfrage-Abonnenten zurückzugeben?

import { Injectable } from '@angular/core';
import { HttpRequest, HttpResponse, HttpErrorResponse, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Router } from '@angular/router';

@Injectable()
export class RequestInterceptor implements HttpInterceptor {
    constructor(
        private router: Router
    ) { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).do((event: HttpEvent<any>) => {
            if (event instanceof HttpResponse) {
                // any way to alter response that gets sent to the request subscriber?
            }
        }, (error: any) => {    
            if (error instanceof HttpErrorResponse) {
                if (error.status === 401 || error.status === 403) {
                    console.log('The authentication session has expired or the user is not authorised. Redirecting to login page.');
                    this.router.navigate(['/login']);
                }
            }
        });
    }
}

Danke.

Antwort #1

Genau wie Marcel Lamothe in seiner Antwort darauf hingewiesen hat, können Sie die Antwort ändern, indem Sie das Ereignis klonen und die Body-Eigenschaft ändern.

import { Injectable } from '@angular/core';
import { HttpRequest, HttpResponse, HttpErrorResponse, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Router } from '@angular/router';

@Injectable()
export class RequestInterceptor implements HttpInterceptor {
    constructor(
        private router: Router
    ) {}

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).map((event: HttpEvent<any>) => {
            if (event instanceof HttpResponse) {
                // change the response body here
                return event.clone({
                    body: 'myCustomResponse'
                });
            }

            return event;
        }).do((event: HttpEvent<any>) => {}, (error: any) => {
            if (error instanceof HttpErrorResponse) {
                if (error.status === 401 || error.status === 403) {
                    console.log('The authentication session has expired or the user is not authorised. Redirecting to login page.');
                    this.router.navigate(['/login']);
                }
            }
        });
    }
}

Antwort #2

Siehe den Abschnitt Unveränderlichkeit im Http-Guide: https://angular.io/guide/http#immutability

Interceptor existieren, um ausgehende Anfragen und eingehende Antworten zu untersuchen und zu verändern. Es mag jedoch überraschend sein zu erfahren, dass die Klassen HttpRequest und HttpResponse größtenteils unveränderlich sind.

Das hat einen Grund: Da die App Anfragen möglicherweise erneut versucht, kann die Interzeptorenkette eine einzelne Anfrage mehrfach verarbeiten. Wenn Anfragen veränderbar wären, würde eine erneut versuchte Anfrage anders sein als die ursprüngliche Anfrage. Unveränderlichkeit stellt sicher, dass die Interzeptoren bei jedem Versuch dieselbe Anfrage sehen.

Es gibt einen Fall, in dem Typsicherheit Sie beim Schreiben von Interzeptoren nicht schützen kann - der Anforderungskörper. Es ist ungültig, einen Anforderungskörper innerhalb eines Interzeptors zu verändern, aber dies wird vom Typsystem nicht überprüft.

Wenn Sie den Anforderungstext ändern müssen, müssen Sie den Anforderungstext kopieren, die Kopie ändern und dann clone() verwenden, um die Anforderung zu kopieren und den neuen Text festzulegen.

Da Anfragen unveränderlich sind, können sie nicht direkt geändert werden. Um sie zu verändern, verwenden Sie clone()

Verwandte Artikel