Javascript 通过手动键入url阻止用户导航

Javascript 通过手动键入url阻止用户导航,javascript,angular,angular-routing,Javascript,Angular,Angular Routing,我正在处理一个带有反应式表单的应用程序,其中用户填写数据,然后单击“下一步”按钮进入下一步。 在我的应用程序中,我需要解决以下问题:用户无法通过手动更改url来浏览网站。如果他/她尝试,预期结果应该是: 弹出窗口,通知所有数据将丢失,用户将返回到第一页 在用户更改url并通过单击“是”接受丢失的数据后,用户应该从第一页开始 只有在刷新页面后,用户才能停留在同一页面上 我首先试着用警卫来做,但后来我找不到办法告诉Angular,只有当用户手动更改url时,警卫才能工作。卫兵在使用“下一步”按钮导航

我正在处理一个带有反应式表单的应用程序,其中用户填写数据,然后单击“下一步”按钮进入下一步。
在我的应用程序中,我需要解决以下问题:用户无法通过手动更改url来浏览网站。如果他/她尝试,预期结果应该是:

  • 弹出窗口,通知所有数据将丢失,用户将返回到第一页

  • 在用户更改url并通过单击“是”接受丢失的数据后,用户应该从第一页开始

  • 只有在刷新页面后,用户才能停留在同一页面上 我首先试着用警卫来做,但后来我找不到办法告诉Angular,只有当用户手动更改url时,警卫才能工作。卫兵在使用“下一步”按钮导航时也工作了——换句话说,“下一步”按钮不再允许我进入下一步

    然后我实现了如下内容:

    export class DirectAccessGuard implements CanActivate {
    
        constructor(private router: Router ) {
        }
    
        canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    
            if (this.router.url === '/') {
                this.router.navigate(['']);
                return false;
            }
            return true;
        }
    }
    
    导出类DirectAccessGuard实现CanActivate{
    构造函数(专用路由器:路由器){
    }
    canActivate(路由:ActivatedRouteSnapshot,状态:RouterStateSnashot):可观察的|承诺|布尔值{
    如果(this.router.url==='/')){
    这个.router.navigate(['']);
    返回false;
    }
    返回true;
    }
    }
    
    在我的每一条路径上都添加了这个防护,它工作得很好,直到我意识到这个解决方案也不是完美的,因为它在刷新页面后将我重定向到第一页。
    我也试过CanDeactivate,但我想这不是我需要的。有什么想法吗?

    角度防护装置无法阻止浏览器执行本机导航操作(刷新、手动更改URL、关闭选项卡等)。因此,一般来说,您希望使用防护和应用程序内弹出窗口来阻止基于角度的导航,如
    router.navigate()
    [routerLink]
    ,但您需要回退到本机技术来处理本机操作

    您可以使用来处理该回退注意:如本文所述,Chromium不允许您输入自定义消息,但您可以在其他浏览器上完成这些步骤

    这里有一个演示,但这里是要点。您可以在本机
    窗口外创建一个可观察对象。在卸载
    事件之前,过滤结果,使其仅在应该时触发(例如
    此。警告
    将更改为您要检查的任何布尔值或表达式),然后订阅它并按如下方式设置返回值:

    fromEvent(window, 'beforeunload')
      .pipe(
        filter(() => this.warn)
      )
      .subscribe((event: BeforeUnloadEvent) => {
        const message = 'You may lose your data if you refresh now';
        (event || window.event).returnValue = message;
        return message;
      });
    

    如果所有页面只有一个URL,则用户无法通过更改URL在页面之间导航。。。。你也可以在每一步保存用户的进度,然后返回到同一个点Jerry,我对第3点有些怀疑。如果允许手动刷新该页面,如何维护上一页数据?这看起来像是一个
    工作流
    ,那么您如何允许用户刷新页面,同时又允许用户停留在工作流的中间(表单链的中间)?如果您能在stackblitz.com上创建一个演示,我将很容易提供一些解决方案。否则我就等你的答复