重定向到404组件,而无需更改浏览器URL,并使历史记录在Angular中表现正确

时间:2019-05-25 13:58:03

标签: javascript angular typescript routing

当后端向我发送404错误(URL有效,只是因为未找到资源,例如http://localhost:4200/post/title-not-exist)时,我希望Angular重定向到我的NotFoundComponent,而无需更改浏览器中的URL。

下面的代码(简体):

constructor(private router: Router, private location: Location) {}

handleError(err: HttpErrorResponse) {
  switch (err.status) {
    case 404:
      url = this.router.routerState.snapshot.url;
      // '**' is set in the app-routing.module.ts
      // { path: '**', component: NotFoundComponent }
      this.router.navigate(['**'], { replaceUrl: false });
      // weird here too
      // without the setTimeout(), replaceState will not work
      setTimeout(() => {
        this.location.replaceState(url);
      });
      break;

    default:
      break;
  }
  return throwError(err);
}

现在,我可以重定向到NotFoundComponent并且URL不变,问题是:

  1. 我的历史将变成这样:
    /post/title-exist/post/not-exist/post/not-exist
    应该是
    /post/title-exist/post/not-exist
    返回功能将卡在这里。
  2. 没有setTimeout()的情况下,location.replaceState()将不起作用,浏览器中的URL变为/**,并且不会更改为之前快照的URL。

1 个答案:

答案 0 :(得分:0)

关键是将this.description = data.description; 中的replaceUrlthis.router.navigate更改为false,如下所示:

true

逻辑背后:

  • this.router.navigate(['**'], { replaceUrl: true }); replaceUrl时,您是浏览器历史记录堆栈中的新历史记录pushing。因此,历史记录堆栈如下所示:

false/post/title-exist/post/title-not-exist

借助/**,它将replaceState()的历史记录更改为/**,从而使历史记录最终变为:

/post/title-not-exist/post/title-exist /post/title-not-exist /**

  • /post/title-not-existreplaceUrl时,您直接modifying是当前历史记录堆栈,这将使您的浏览器历史记录变为:

true /post/title-exist /post/title-not-exist

然后,在/**的帮助下,历史记录变为:

replaceState() /post/title-exist /post/title-not-exist /**