好久没登录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([])
)
)