目錄

[Angular]使用HttpInterceptor 處理HttpRequest和HttpResponse

通常前端專案很常使用HttpClient來與後端API互動,而如果需要Token認證或需要在每次的請求處理一些log機制等就需要在每一次實作HttpClient都撰寫相似的程式碼….


自從 Angular 4.3 開始新增了HttpInterceptor 攔截器,可以處理每次的請求與回應間須"加工"的過程,其類似ASP.NET Core中的Middleware

Alt text


接下來為如何實作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);
  }
}

這邊會用到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