Angular request and response Interceptor usage
请求拦截器 (Request Interceptor)
import {
HttpRequest,
HttpHandler,
HttpEvent
} from '@angular/common/http';
@Injectable()
class JWTInterceptor implements HttpInterceptor {
constructor(private userService: UserService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const JWT = `Bearer ${this.userService.getToken()}`;
req = req.clone({
setHeaders: {
Authorization: JWT
}
});
return next.handle(req);
}
}
如果我们想要注册新的拦截器 (interceptor),我们需要实现 HttpInterceptor
接口,然后实现该接口中的 intercept
方法。
export interface HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>;
}
需要注意的是,请求对象和响应对象必须是不可修改的 (immutable)。因此,我们在返回请求对象前,我们需要克隆原始的请求对象。
next.handle(req)
方法使用新的请求对象,调用底层的 XHR 对象,并返回响应事件流。
响应拦截器 (Response Interceptor)
@Injectable()
class JWTInterceptor implements HttpInterceptor {
constructor(private router: Router) {}
intercept(req: HttpRequest < any > ,
next: HttpHandler): Observable < HttpEvent < any >> {
return next.handle(req).map(event => {
if (event instanceof HttpResponse) {
if (event.status === 401) {
// JWT expired, go to login
}
}
return event;
}
}
}
响应拦截器可以通过在 next.handle(req)
返回的流对象 (即 Observable 对象) 上应用附加的 Rx 操作符来转换响应事件流对象。
接下来要应用 JWTInterceptor
响应拦截器的最后一件事是注册该拦截器,即使用 HTTP_INTERCEPTORS
作为 token,注册 multi Provider:
[{ provide: HTTP_INTERCEPTORS, useClass: JWTInterceptor, multi: true }]
More examples:
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;
});
}
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);
}
});
}
}
For Angular6+ and RXJS6+:
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
* */
}
}