重定向到 404 组件而不更改浏览器 URL,并使历史记录在 Angular 中正常运行

fun*_*kid 2 javascript routes typescript angular

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

\n\n

代码如下(简化):

\n\n
constructor(private router: Router, private location: Location) {}\n\nhandleError(err: HttpErrorResponse) {\n  switch (err.status) {\n    case 404:\n      url = this.router.routerState.snapshot.url;\n      // \'**\' is set in the app-routing.module.ts\n      // { path: \'**\', component: NotFoundComponent }\n      this.router.navigate([\'**\'], { replaceUrl: false });\n      // weird here too\n      // without the setTimeout(), replaceState will not work\n      setTimeout(() => {\n        this.location.replaceState(url);\n      });\n      break;\n\n    default:\n      break;\n  }\n  return throwError(err);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,我可以重定向到NotFoundComponent并且 URL 没有更改,问题是:

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

fun*_*kid 5

更新

\n\n

用于skipLocationChange保留原始 URL,replaceUrl不再需要。
\n参考这里

\n\n

原来的

\n\n

关键点是将replaceUrlinthis.router.navigate从更改falsetrue,如下所示:

\n\n
this.router.navigate([\'**\'], { replaceUrl: true });\n
Run Code Online (Sandbox Code Playgroud)\n\n

背后逻辑:

\n\n\n\n

/post/title-exist\xe2\x86\x92 /post/title-not-exist\xe2\x86\x92/**

\n\n

并在 的帮助下replaceState(),将/**历史记录更改为/post/title-not-exist,这使得历史记录最终变为:

\n\n

/post/title-exist\xe2\x86\x92 /post/title-not-exist\xe2\x86\x92/** /post/title-not-exist

\n\n
    \n
  • replaceUrl是 时true,你直接修改当前的历史记录堆栈,这使得你的浏览器历史记录变成这样:
  • \n
\n\n

/post/title-exist\xe2\x86\x92/post/title-not-exist /**

\n\n

然后,在 的帮助下replaceState(),历史变成:

\n\n

/post/title-exist\xe2\x86\x92/post/title-not-exist /** /post/title-not-exist

\n