通常前端專案很常使用HttpClient來與後端API互動,而如果需要Token認證或需要在每次的請求處理一些log機制等就需要在每一次實作HttpClient都撰寫相似的程式碼….
自從 Angular 4.3 開始新增了HttpInterceptor 攔截器,可以處理每次的請求與回應間須"加工"的過程,其類似ASP.NET Core中的Middleware
接下來為如何實作HttpInterceptor攔截器 (範例為 Angular 13)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import { Injectable } from '@angular/core';
import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class HTTPInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
//在發出request前要處理的部分
return next.handle(req);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
|
@NgModule({
bootstrap: [AppComponent],
imports: [...],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: HTTPInterceptor,
multi: true
}
]
})
export class AppModule {}
|
過來看看進階用法
這邊示範當拿到token(最常見為登入所取得的JWT),來當每一次request 的認證
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
import { Injectable } from '@angular/core';
import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class HTTPInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
//在每一次request 均加入Authorization header
req = req.clone({
setHeaders: {
Authorization: `Bearer ${token}`,
},
})
return next.handle(req);
}
}
|
2.2 error handle
這邊會用到rxjs 相關的應用(observable & operators)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
import { Injectable } from '@angular/core';
import {
HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class HTTPInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
const retryCount = 3;
const retryWaitMilliSeconds = 1000;
return next.handle(req).pipe(
//當response 為特定code 作相應處理
catchError((err: HttpErrorResponse) => {
switch (err.status) {
case 400:
//400 code handle
break;
case 401:
//401 code handle
break;
case 404:
//404 code handle
break;
default:
break;
}
return EMPTY;
}),
//retry 3次、間隔1000毫秒
retry({ count: retryCount, delay: retryWaitMilliSeconds })
);
}
}
|
Angular HTTP Interceptor
Rxjs retry
Rxjs catchError