我想使用角度拦截器,以便按照官方角度页面(https://angular.io/guide/http#using-interceptors-for-caching)中的示例在本地存储中缓存http响应,这是我的拦截器:
@Injectable()
export class CachingInterceptor implements HttpInterceptor {
constructor(
private cache: RequestCache,
private store: Store,
private notifs: NotificationsService
) {}
intercept(
req: HttpRequest<any>,
next: HttpHandler
):Observable<HttpEvent<any>> {
if (req.method == "POST" || req.method == "PUT") return next.handle(req);
let cachedObject = this.cache.get(req); //get the cached response
const response: HttpResponse<any> = cachedObject?.response;
const expired: boolean = cachedObject?.expired;
if (response && !expired) return of(response);
else return this.sendRequest(req, next, this.cache, response);
}
private sendRequest(
req: HttpRequest<any>,
next: HttpHandler,
cache: RequestCache,
cachedResp?: HttpResponse<any>
): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
tap((event) => {
if (event instanceof HttpResponse) {
if (req.method == "GET" && event.status == 200) cache.put(req, event);
}
}),
catchError((err) => this.handleError(err, cachedResp))
);
}
}
我可以在此函数内部记录缓存的响应,还可以在拦截函数内部订阅of(response)
并获取缓存的响应。
但是,当订阅被拦截的http服务时,我没有任何值。
这是缓存服务
@Injectable({
providedIn: "root",
})
export class RequestCache {
put(req: HttpRequest<any>, response: HttpResponse<any>): void {
const url = req.urlWithParams;
const entry = { response, fetched: Date.now() };
localStorage.setItem(url, JSON.stringify(entry));
}
get(
req: HttpRequest<any>
): { response: HttpResponse<any>; expired: boolean } | undefined {
const url = req.urlWithParams;
let cached = localStorage.getItem(url);
if (!cached) return;
let cacheObject = JSON.parse(cached);
const isExpired = cacheObject.fetched < Date.now() - maxAge;
return { response: cacheObject.response, expired: isExpired };
}
}