【发布时间】:2021-09-13 16:11:24
【问题描述】:
我发现我的 CanActivate 防护 (Angular 10.2.5) 出现了奇怪的行为:
export class VersionGuardService implements CanActivate {
constructor(private router: Router, private http: HttpClient){
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
console.log("In the Guard");
return this.http.request<any>('get',`https://jsonplaceholder.typicode.com/users`).pipe(
tap(resp => console.log("Response: ", resp)),
map(resp => false)
);
//return of(false);
}
}
app-routing.module.ts 中的路由如下所示:
const routes: Routes = [
{
path: 'login',
component: LoginComponent,
canActivate: [VersionGuardService]
},
{
path: 'logout',
component: LogoutComponent
},
{
path: 'error',
component: ErrorComponent
},
{
path: '',
redirectTo: 'login',
pathMatch: 'full'
}
];
如果我使用上述代码调用应用程序,我会收到 Too many calls to Location or History APIs within a short timeframe 错误(在 Firefox 中)。当我在浏览器中检查控制台输出时 - 确实有很多(近 200 个)条目带有 In the Guard 消息。如果我检查开发工具中的网络选项卡,我会在网络开发工具选项卡的“已转移”列中看到大量远程服务 https://jsonplaceholder.typicode.com/users 上的 GET 调用和 NS_BINDING_ABORTED 消息。
编辑 1 http 调用的流不提供任何数据(控制台日志中没有以“响应:”开头的条目。因此,http 调用后如何构造管道不是问题。
问题是为什么会这样?是什么原因导致 canActivate 方法执行了多次?
例如,如果我删除 http 调用并保持这样:
@Injectable()
export class VersionGuardService implements CanActivate {
constructor(private router: Router, private http: HttpClient){
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
console.log("In the Guard");
return of(false);
}
}
它按预期工作(在 Firefox 控制台中只有一个条目“In the Guard”)。
我想使用 Guard 的原因是在网站初始化时检查应用程序版本兼容性(与后端服务),并决定加载登录窗口或重定向到错误消息站点。
编辑 2 如果我将警卫移动到路线中的“稍后”链接(我的意思是:稍后在应用程序中执行的链接)并且警卫按预期工作。所以我认为这是应用程序初始化的问题,所以我在第一个链接上准备了带有保护的 stackblitz: https://stackblitz.com/edit/angular-ivy-qgfdk3 它也可以按预期工作。
提前感谢您的帮助!
【问题讨论】:
-
请尝试在 http 请求中添加 take(n) 运算符和 catchError(() => of(false)) 块
-
不幸的是,事实并非如此,流不提供任何数据,我提供了额外的描述来标记
标签: angular canactivate