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([])
     )
   )

你可能感兴趣的:(web前端,angular,javascript)