2

就像之前展示的那样,目前在首次进入登录页面时会发生401报错,先说一下为什么会发生错误。
userService:

constructor(protected httpClient: HttpClient,
              private router: Router) {
      this.initCurrentLoginUser().subscribe();
  }

我们在userService的构造函数中订阅了请求当前登陆用户的方法,其中就会向后台发送/api/user/me的请求,但是我们在后台中设定了权限管理,此时没有用户登录如果进行访问的话就会报401错误。

我们可以有三种解决方法:
一:让后台开放/user/me的权限
虽然说可以解决,但是总感觉并不是很规范就没有采取。

二:在错误处理时如果当前页面为登录页面则不弹出报错框给用户
虽然表面上没有报错提示,但是查看控制台时还是会有报错提示,因为我们是根据响应判断的错误类型再给用户进行提示,但是请求还是传给了后台,所以还是会有401报错。

三:前台新增拦截器,当请求的url为/api/user/me并且当前路由是/login时不将请求继续发送,也就是直接取消这个请求,那么自然也不会有401报错。

期间遇到的问题:
获取当前路由为空
起初是通过如下代码来获取当前路由的:

constructor(private readonly injector: Injector) {
    this.activatedRoute.events.subscribe(
      (event) => {
        console.log(event);
        if (event instanceof NavigationEnd){
          this.currentUrl = event.url;
        }
      }
    )
  }

我们可以发现这是当有router.event发生时才会传给我们url,在拦截器中进行如下打点:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.log(req.url)
    console.log(this.currentUrl)
}

图片.png
我们可以发现router事件是在此拦截器起作用之后发生的,也就是说我们如果这么获取路由的话第一个路由必定为空,并且如果我们让他为空的时候也算进拦截条件的话有可能会引发其他问题。
所以我们要换一种获取路由的方法:

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const currentUrl = this.activatedRoute.routerState.snapshot.url;
    console.log(req.url)
    console.log(currentUrl)
}

此时我们再去控制台中查看执行情况就符合我们的预期了。
图片.png

之后就是如何“取消”这个请求。
查找官方文档和网上相关资料后并没有发现这类操作如何实现,如果我们不进行处理的话就会发生如下报错:
图片.png

传过来的请求就必须要进行相应的转发操作,不能直接不进行转发。
后来尝试人为构造并返回一个空的Observable<HttpEvent<any>>,如下:

return of<HttpEvent<any>>();

报错消失,重新进入登录页面进行测试发现没有401报错,与预期一致。


李明
441 声望19 粉丝