具有拦截器读取缓存值



我正在尝试让我的拦截器从我的缓存中读取,以查看当我离线时是否已经缓存了 post 请求。如果是这样,我会返回缓存的本地数据并显示它。缓存正在使用 Ionic 存储缓存。

在这个例子中,我只检查了一个 url 模式 (api/dfrs/id(,并且我缓存了该值。 我正在循环缓存并在设置了某个键时获取值。每个缓存值都是后置请求本身。

最终会找到该值,但由于获取该值的方法是异步的,因此在返回缓存结果之前,侦听器代码将继续存在。

所以我试图解决两个问题

1(让第一个if语句中的代码在该promise方法上运行

2( 将缓存请求的正文作为可观察对象返回,以便我的视图可以使用它

任何帮助将不胜感激。谢谢

令牌拦截器

'

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse, HttpHeaders, HttpResponse } from '@angular/common/http';
import { Observable, throwError, BehaviorSubject, from, EMPTY, NEVER, of } from 'rxjs';
import { catchError, filter, take, switchMap, finalize, map } from 'rxjs/operators';
import { AuthService } from '../admin/users/auth.service';
import { Router } from '@angular/router';
import { Storage, IonicStorageModule } from '@ionic/storage';
import { CacheSaveDataService } from './cache-save-data.service';
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
private isRefreshing = false;
private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
constructor(public authService: AuthService, public cacheSaveDataService: CacheSaveDataService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (!this.cacheSaveDataService.status.connected && request.method === 'GET' &&
request.url.indexOf('api/dfrs/id/') !== -1) {
return next.handle(request).pipe (
map((event: any) => {
let val = this.getCachedResult(request);
return (Observable.create(val));
})
)
} else if (!this.cacheSaveDataService.status.connected && request.url.indexOf('authenticate') === -1
&& request.url.indexOf('logout') === -1  && (request.method === 'PUT' || request.method === 'POST')) {
const result = this.cacheSaveDataService.setStorageRequest(request);
return next.handle(request).pipe(
map((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
console.log('event--->>>', event);
}
return event;
}),
catchError((error: HttpErrorResponse) => {
let data = {};
data = {
reason: error && error.error && error.error.reason ? error.error.reason : '',
status: error.status
};
return throwError(error);
}));
} else {
const userId = this.getUserId();
if (this.authService.getJwtToken()) {
request = this.addToken(request, this.authService.getJwtToken(), userId);
}
return next.handle(request).pipe(catchError(error => {
if (error instanceof HttpErrorResponse && error.status === 401) {
return this.handle401Error(request, next);
} else {
if (error.status === 405) { //|| error.status === 500) {
this.authService.backToLogin();
}
console.log('error, not logged in');
return throwError(error);
}
}));
}
console.log ('Done Intercepter');
}
async getCachedResult(request) {
const keys = await this.cacheSaveDataService.getKeys();
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (key.indexOf('reqcache') !== -1) {
return  await this.getKeyValue(key, request);
}
}
}
async getKeyValue(key, request) {
const res = await this.cacheSaveDataService.get2(key);
const val: any = res;
if (val.url === request.url) {
return val;
}
}
private addToken(request: HttpRequest<any>, token: string, userId: string) {
const headers = new HttpHeaders({
'Authorization': `Bearer ${token}`,
'userId': userId
});
return request.clone({headers});
}
private handle401Error(request: HttpRequest<any>, next: HttpHandler) {
const userId = this.getUserId();
if (!this.isRefreshing) {
this.isRefreshing = true;
this.refreshTokenSubject.next(null);
return this.authService.refreshToken().pipe(
switchMap((token: any) => {
this.isRefreshing = false;
this.refreshTokenSubject.next(token.jwt);
return next.handle(this.addToken(request, token.jwt, userId));
}));
} else {
return this.refreshTokenSubject.pipe(
filter(token => token != null),
take(1),
switchMap(jwt => {
return next.handle(this.addToken(request, jwt, userId));
}));
}
}
private getUserId() {
const user: any = JSON.parse(localStorage.getItem('user') );
let userId = '0';
if (user !== undefined && user !== null) {
userId = user._id;
}
return userId;
}
}

'

cache-save-data.service.ts `

import { Injectable } from '@angular/core';
import { Storage, IonicStorageModule } from '@ionic/storage';
import { Network } from '@capacitor/core';
import { HttpClient } from '@angular/common/http';
import { SharedService } from '../shared/shared.service';
import { DFRPhotoService } from '../dfr/daily-summary/dfr-photo/dfr-photo.service';
import { LoadingController } from '@ionic/angular';
@Injectable({
providedIn: 'root'
})
export class CacheSaveDataService {
status = null;
handler;
loaderElement;
constructor(
public storage: Storage,
private httpClient: HttpClient,
private sharedService: SharedService,
private loadingController: LoadingController) {
this.status = this.getStatus();
if (this.handler === undefined) {
console.log('Add Listener ', status);
this.handler = Network.addListener('networkStatusChange', (status) => {
console.log('Network status changed! ', status);
const oldStatus = this.status;
this.status = status;
if (this.status.connected && !oldStatus.connected) {
this.saveCachedData();
}
this.status = status;
if (!this.status.connected) {
this.sharedService.showNotification('Network connection has terminated.', 'danger', 5000);
}
});
}
}

public async setItem(key, value) {
return await this.storage.set(key, value);
}
public async setStorageRequest2(request) {
const cacheKey = 'reqcache-' + this.sharedService.generateId();
return await this.storage.set(cacheKey, request);
}
public async setStorageRequest(request) {
this.sharedService.showNotification('User is offline. Service Request Cached', 'warning', 2000);
const cacheKey = 'reqcache-' + this.sharedService.generateId() + '-' + request.urlWithParams;
return await this.storage.set(cacheKey, request);
}
public async get(settingName){
return await this.storage.get(`setting:${ settingName }`);
}
public async get2(settingName) {
return await this.storage.get(settingName);
}
public async remove(settingName){
return await this.storage.remove(settingName);
}
public clear() {
this.storage.clear().then(() => {
console.log('all keys cleared');
});
}
public async getKeys() {
return await this.storage.keys();
}
public async getStatus() {
this.status = await Network.getStatus();
}

}

'

//dfr.service.ts (仅限类中的方法( `

public getDFRByDfrId(id: string) {
return this.httpClient.get(environment.apiURL + this.path + '/id/' + id)
.pipe(
map((res: any) => {
return res.data;
})
);
}

'

view.ts(仅限订阅( `

this.dfrService.getDFRByDfrId(paramMap.get('id')).subscribe(val => {
this.currentDFR = val;
});

'

我希望返回缓存请求的正文

LOL终于明白了。我无法听从承诺,然后不得不返回一个可观察的。 希望这会帮助某人;0

替换此代码

return next.handle(request).pipe (
map((event: any) => {
let val = this.getCachedResult(request);
return (Observable.create(val));
})
)

return from(this.getCachedResult(request)).pipe (
mergeMap(data => {
return of(new HttpResponse({ body: data.body }))
})
)

最新更新