好久沒登錄CDSN的賬號,居然有人給我點贊,還有人關注我了,哈哈,無名之輩的開心就是這麼簡單,謝謝(๑╹◡╹)ノ"""
什麼是攔截器
迴歸今天的主題, 我建議大家主要是去看官方文檔的攔截請求和響應,跳到頂部,可以下載官方例子源碼的。
攔截器就是在發送請求給服務器之前,攔截請求,隱式進行處理。
也可以在接受服務器的響應之後,攔截響應,隱式進行處理。
簡單的應用就像官方說的,記日誌,緩存等等,我也用其實現了在請求數據時,改變光標的類型的一個小功能。
使用攔截器
- 自定義的攔截器CachingInterceptor繼承接口HttpInterceptor,實現其中的方法intercept
- 攔截請求
intercept(req: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
// 在發送請求給服務器之前,攔截請求的處理
// 強調下雖然攔截器有能力改變請求和響應,但 HttpRequest 和 HttpResponse 實例的屬性卻是隻讀
// 此讓它們基本上是不可變的。
//要想修改該請求,就要先克隆它,並修改這個克隆體,然後再把這個克隆體傳給 next.handle()。
const secureReq = req.clone({ url: req.url.replace('http://', 'https://')});
//next.handle(),把請求傳給下一個攔截器,最終傳給後端處理器。
return next.handle(secureReq);
}
碎碎念一下, intercept() 和 handle() 方法返回的是 HttpEvent 的可觀察對象,而不是大多數 HttpClient 中的方法那樣返回 HttpResponse 的可觀察對象。HttpEvent 這個可觀察對象很有用,他擁有以下六種事件,在官方案例監聽進度事件起到了重要作用。
export declare enum HttpEventType {
/**
* The request was sent out over the wire.
*/
Sent = 0,
/**
* An upload progress event was received.
*/
UploadProgress = 1,
/**
* The response status code and headers were received.
*/
ResponseHeader = 2,
/**
* A download progress event was received.
*/
DownloadProgress = 3,
/**
* The full response including the body was received.
*/
Response = 4,
/**
* A custom event from an interceptor or a backend.
*/
User = 5
}
return next.handle(noHeaderReq).pipe(
// tap只是一個監視作用的操作符,不產生任何副作用,返回與源相同的Observable
tap({
// 在請求結束後攔截響應做一些處理
next: event=>{
if (event instanceof HttpResponse) {
cache.put(req, event); // Update the cache.
}
},
error: error=>{
console.error('on error', error.message);
},
complete: () => document.body.style.cursor="" // Reset cursor
})
);
- 提供服務
告訴DI系統我們提供了啥攔截器,在app.module.ts中provides寫入自定義的服務
{ provide: HTTP_INTERCEPTORS, useClass: CachingInterceptor, multi: true },
也可以在此服務文件頭部這樣寫
@Injectable({
providedIn: 'root'
})
- 使用攔截器
HttpClient使用時會隱式調用,不需要我們再加任何代碼
this.http.get(uri,{params}).pipe(
map(value=>value["data"]["record"]["children"]),
catchError(err =>
of([])
)
)