Angular 按照開發人員提供的 HTTP Interceptors 的順序來
依次
調用這些攔截器。
例如,考慮這種例子,開發人員希望處理 HTTP 請求的身份驗證,并在将它們發送到伺服器之前記錄它們。要完成這個場景,可以按順序先提供 AuthInterceptor,然後再提供 LoggingInterceptor. Angular 應用發送出的請求,将從 AuthInterceptor 流向 LoggingInterceptor。相應的,這些請求的響應将反向流動,即從 LoggingInterceptor 傳回到 AuthInterceptor.
以下是該過程的圖形化表示:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SM5cTN1U2YwMGM2MGM5kDNzYzX0MTOzADM1EzLcBTMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
流程中的最後一個攔截器始終是處理與伺服器通信的 HttpBackend.
SAP Spartacus 開發中為令牌
HTTP_INTERCEPTORS
提供的絕大多數 Interceptor,都定義在 barrel 檔案即
index.ts
内:
這些 Interceptor 彼此之間在業務上并沒有依賴關系,是以沒有嚴格的先後順序定義要求。
大多數 HttpClient 方法傳回
HttpResponse<any>
的 observables。
HttpResponse
類本身實際上是一個事件,其類型為
HttpEventType.Response
. 但是,單個 HTTP 請求可以生成多個其他類型的事件,包括上傳和下載下傳進度事件。
HttpInterceptor.intercept()
和
HttpHandler.handle()
方法傳回
HttpEvent<any>
的 observables.
下面是 SAP Spartacus 一個具體的 Interceptor 例子:
許多攔截器隻關心傳出請求并從 next.handle() 傳回事件流而不修改它。 然而,一些攔截器需要檢查和修改來自 next.handle() 的響應; 這些操作需要識别到流中的所有這些事件。
上圖是 Spartacus Cart Checkout 場景使用 Interceptor 進行錯誤處理的一個例子。
首先從
rxjs/operators
裡導入 Rxjs 執行錯誤處理的操作符
catchError
:
當 HTTP 互動出現錯誤時,傳入 catchError 操作符的箭頭函數觸發,如果觸發時的執行個體變量
response
的類型為
HttpErrorResponse
,那麼繼續判斷目前的路由路徑,是否包含了 checkout 片段:
這個判斷通過下列函數執行:
/**
* Returns true if the parameter semantic route is part of "checkout"
* Checkout semantic routes:
* checkout
* checkoutPaymentType
* CheckoutShippingAddress
* checkoutDeliveryMode
* checkoutPaymentDetails
* checkoutReviewOrder
* checkoutLogin
* @param semanticRoute
*/
protected isUserInCheckoutRoute(semanticRoute?: string): boolean {
return semanticRoute?.toLowerCase().startsWith('checkout') ?? false;
}