我正在尝试在我的Angular2应用程序上实现刷新令牌.我采取乐观的方法,而不是在发出请求之前检查访问令牌是否过期,我正在发出请求,如果它返回401代码,我将通过请求新的令牌并将其保存到本地存储来刷新访问令牌.
这是我的代码片段:
getWithParams<T>(serviceUrl: string, params: URLSearchParams): Observable<T> {
return super.getWithParams<T>(serviceUrl, params)
.retryWhen((error) => {
return error
.filter((e) => e.status === 401)
.scan((acc, value) => {
return acc + 1;
}, 0)
.takeWhile(acc => acc < 3)
.flatMap(() => this.tokenRefreshService.refreshToken())
.delay(1000);
});
}
Run Code Online (Sandbox Code Playgroud)
值得一提的是,super.getWithParams通过从本地存储中检索访问令牌来设置访问令牌.
方法调用tokenRefreshService.refreshToken()获取新的访问令牌并将其保存到本地存储.
我面临的问题是,当重试请求时,它正在使用旧的访问令牌,也就是说,它不会再调用super.getWithParams来重建请求.它只是重试现有的观察.
有没有办法再次建立请求?或者查看失败的observable的请求标头?
我正在尝试为Android创建一个Angular 2组件,用于显示特定路径的内容.为此,我创建了以下app-routing.module:
@NgModule({
imports: [
NativeScriptRouterModule.forRoot([
{ path: '', component: HomeComponent },
{ path: 'folder-content/:path', component: FolderContentComponent },
])
],
exports: [NativeScriptRouterModule]
})
Run Code Online (Sandbox Code Playgroud)
为了完整性,这里是folder-content.xml的xml
<StackLayout>
<GridLayout row="auto, *" row="2">
<ListView [items]="getContent(currentPath)">
<template let-item="item">
<GridLayout columns="auto, *" [nsRouterLink]="['/folder-content', item.path]">
<GridLayout columns="auto" rows="auto" cssClass="favorite-wrap">
<Image id="imgFav" [src]="item.isFile() ? 'res://ic_add_to_fav_1': 'res://folder'" stretch = "none" cssClass="icon-image"></Image>
</GridLayout>
<StackLayout col="1">
<Label [text]="item.name" cssClass="info-bigger"></Label>
<Label [text]="item.path" cssClass="info-orange"></Label>
</StackLayout>
</GridLayout>
</template>
</ListView>
</GridLayout>
</StackLayout>
Run Code Online (Sandbox Code Playgroud)
每次点击列表项时,我都想导航到同一页面,但是使用不同的参数(这可以按预期工作).
问题是当我尝试向后导航(使用物理后退按钮)时,我被重定向到HomeComponent而不是FolderContentComponent.
我尝试使用以下代码段打印路由器事件以获取更多信息:
router.events.forEach((event) => {
console.log(event);
});
Run Code Online (Sandbox Code Playgroud)
当从默认路径导航到 …
我有一个发出HTTP请求的Angular服务.该服务的主要工作是刷新访问令牌并在请求结果为401时重试请求.该服务还能够宽限期地处理多个并发请求:如果有3个请求导致401,则令牌将只刷新一次,所有3个请求将被重播.以下GIF总结了此行为:

我的问题是我似乎无法测试这种行为.最初,我的测试总是因超时而失败,因为我没有调用我的订阅或错误方法.添加fakeAsync之后我再也没有得到超时,但我的观察者仍然没有被调用.我还注意到,如果我从tokenObservable中删除共享运算符,则会调用我的测试中的订阅,但通过这样做,我将失去多播的好处.
这是不能正常工作的测试
it('refreshes token when getting a 401 but gives up after 3 tries', fakeAsync(() => {
const errorObs = new Observable(obs => {
obs.error({ status: 401 });
}).pipe(
tap(data => {
console.log('token refreshed');
})
);
const HttpClientMock = jest.fn<HttpClient>(() => ({
post: jest.fn().mockImplementation(() => {
return errorObs;
})
}));
const httpClient = new HttpClientMock();
const tokenObs = new Observable(obs => {
obs.next({ someProperty: 'someValue' });
obs.complete();
});
const AuthenticationServiceMock = jest.fn<AuthenticationService>(() => ({
refresh: jest.fn().mockImplementation(() => {
return …Run Code Online (Sandbox Code Playgroud)