angular攔截器的使用(緩存)

好久沒登錄CDSN的賬號,居然有人給我點贊,還有人關注我了,哈哈,無名之輩的開心就是這麼簡單,謝謝(๑╹◡╹)ノ"""

什麼是攔截器

迴歸今天的主題, 我建議大家主要是去看官方文檔的攔截請求和響應,跳到頂部,可以下載官方例子源碼的。
攔截器就是在發送請求給服務器之前,攔截請求,隱式進行處理。
也可以在接受服務器的響應之後,攔截響應,隱式進行處理。
簡單的應用就像官方說的,記日誌,緩存等等,我也用其實現了在請求數據時,改變光標的類型的一個小功能。

使用攔截器

  1. 自定義的攔截器CachingInterceptor繼承接口HttpInterceptor,實現其中的方法intercept
  2. 攔截請求
  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
}
  1. 攔截響應
    在next.handle()後利用rxjs管道處理下發給此請求訂閱者。rxjs不熟悉的同學,可以看下官方文檔rxjs例子,注意rxjs的pipe是在RxJS 5.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
    })
  );
  1. 提供服務
    告訴DI系統我們提供了啥攔截器,在app.module.ts中provides寫入自定義的服務
 { provide: HTTP_INTERCEPTORS, useClass: CachingInterceptor, multi: true },

也可以在此服務文件頭部這樣寫

@Injectable({
  providedIn: 'root'
})
  1. 使用攔截器
    HttpClient使用時會隱式調用,不需要我們再加任何代碼
this.http.get(uri,{params}).pipe(
     map(value=>value["data"]["record"]["children"]),
     catchError(err => 
       of([])
     )
   )
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章