在 http 拦截器中使用 observable 时,请求被无限触发
Request is being fired infinitely when using observable in http interceptor
我对依赖于 observable 的 http 拦截器有疑问。整个事情以无限循环结束,一遍又一遍地调用相同的 URL。
但是,我搜索了与我的类似的其他解决方案(参见 Async HTTP Interceptors with Angular 4.3),除了不同的 rxjs 版本外,我看不出有什么大的不同。拦截器如下所示:
@Injectable()
export class MyHttpInterceptor implements HttpInterceptor {
constructor(private loginSvc: LoginService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.loginSvc.currentUser$.pipe(
mergeMap(x => {
if (x) {
console.log("User is authenticated, usually I would add a bearer token to the request here...");
}
return next.handle(req);
})
);
}
}
有人可以指出我在 Angular http 拦截器中犯的错误吗?您可以在此处查看整个工作示例:
设置如下:
- login.service.ts:该服务封装了认证用户。它通过一个 BehaviorSubject 和一个相应的 Observable 来做到这一点。最初,主题用 null 初始化,表示未登录用户。
- login.component.ts 第 17 行:一旦路由 /login 打开,我们就会模拟一个应该对用户进行身份验证的请求。该请求只是 returns 来自模拟成功登录的 jsonplaceholder 的用户。
- 我们正在通过 LoginService 填充用户,以便所有感兴趣的各方/观察者都能了解新登录的用户。 http 拦截器就是这些感兴趣的团体之一。
为了重现该问题,请打开 StackBlitz 上的 http 拦截器并取消注释其中所述的行。在开发人员控制台中,您会看到无限循环中出现的重复日志消息。 注意:如果等待时间过长,会导致浏览器选项卡崩溃/window!因此,如果您在能够重现问题后取消注释,请快速再次注释掉这些行! 在 StackBlitz 上,您可以简单地使用快捷键 STRG + / 来切换多行注释!
提前致谢!
我调试了你的代码。
当您的 http 请求完成时,您将新值推送给用户主题(方法 signIn
)。您的中断流依赖于 currentUser$
,一旦新用户值到达,中断器将重新开始。我修复了中断器以避免此问题,并根据当前用户停止。
我对依赖于 observable 的 http 拦截器有疑问。整个事情以无限循环结束,一遍又一遍地调用相同的 URL。 但是,我搜索了与我的类似的其他解决方案(参见 Async HTTP Interceptors with Angular 4.3),除了不同的 rxjs 版本外,我看不出有什么大的不同。拦截器如下所示:
@Injectable()
export class MyHttpInterceptor implements HttpInterceptor {
constructor(private loginSvc: LoginService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.loginSvc.currentUser$.pipe(
mergeMap(x => {
if (x) {
console.log("User is authenticated, usually I would add a bearer token to the request here...");
}
return next.handle(req);
})
);
}
}
有人可以指出我在 Angular http 拦截器中犯的错误吗?您可以在此处查看整个工作示例:
设置如下:
- login.service.ts:该服务封装了认证用户。它通过一个 BehaviorSubject 和一个相应的 Observable 来做到这一点。最初,主题用 null 初始化,表示未登录用户。
- login.component.ts 第 17 行:一旦路由 /login 打开,我们就会模拟一个应该对用户进行身份验证的请求。该请求只是 returns 来自模拟成功登录的 jsonplaceholder 的用户。
- 我们正在通过 LoginService 填充用户,以便所有感兴趣的各方/观察者都能了解新登录的用户。 http 拦截器就是这些感兴趣的团体之一。
为了重现该问题,请打开 StackBlitz 上的 http 拦截器并取消注释其中所述的行。在开发人员控制台中,您会看到无限循环中出现的重复日志消息。 注意:如果等待时间过长,会导致浏览器选项卡崩溃/window!因此,如果您在能够重现问题后取消注释,请快速再次注释掉这些行! 在 StackBlitz 上,您可以简单地使用快捷键 STRG + / 来切换多行注释!
提前致谢!
我调试了你的代码。
当您的 http 请求完成时,您将新值推送给用户主题(方法 signIn
)。您的中断流依赖于 currentUser$
,一旦新用户值到达,中断器将重新开始。我修复了中断器以避免此问题,并根据当前用户停止。