7

如何说服 Angular 4 路由器在我的应用程序中禁用直接浏览器导航?

我已经查看了路由器挂钩CanActivateCanDeactivate实现了它们,但CanDeactivate在使用直接浏览器导航时根本不会触发。

我可以CanActivate用来阻止 url,但只能在应用程序重新启动后使用,这需要时间和浏览器窗口中的意外更改。

我希望能够在应用程序重新启动之前捕获直接浏览器导航。

如果这有帮助:我想完全禁止直接浏览器导航,所以我不需要允许某些 URL 并禁用其他 URL 的解决方案。

这是我的路由器定义:

const routes: Routes = [
  { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
  { path: 'dashboard', component: DashboardComponent, canActivate: [RouteGuardService] },
  { path: 'users', component: UsersMainComponent, canActivate: [RouteGuardService] },
  { path: 'vendors', component: VendorMainComponent, canActivate: [RouteGuardService] },
  { path: 'invoices', component: InvoicesMainComponent, canActivate: [RouteGuardService] },
  { path: 'offers' , component: EsdMainComponent, canActivate: [RouteGuardService] },
  { path: 'settings' , component: SettingsMainComponent, canActivate: [RouteGuardService] },
  // Callback MUST not be route guard protected.
  { path: 'callback' , component: CallbackComponent },
  { path: 'createvendor' , component: CreateVendorsComponent, canActivate: [RouteGuardService] },
  { path: 'customerdashboard' , component: CustomerDashboardComponent, canActivate: [RouteGuardService] },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: [RouteGuardService]
})
export class AppRoutingModule { }
4

2 回答 2

7

The following solution is not an Angular based one. As Maximus explained in his answer this is a browser issue and therefor the solution must be browser based.

This solution is derived from an answer on this site (see here) I have written a little (typescript) service with the following three methods:

  private preventNavigation(): void {
    const location = window.document.location;
    const originalHashValue = location.hash;

    window.setTimeout(() => {
      location.hash = 'preventNavigation' + (9999 * Math.random());
      location.hash = originalHashValue;
    }, 0);
  }

  public disableBrowserNavigation(): void {
    window.addEventListener('beforeunload', this.preventNavigation, false);
    window.addEventListener('unload', this.preventNavigation, false);
  }

  public enableBrowserNavigation(): void {
    window.removeEventListener('beforeunload', this.preventNavigation);
    window.removeEventListener('unload', this.preventNavigation);
  }

This works fine but I'm still open to other solutions.

于 2017-08-02T03:40:20.860 回答
3

如何说服 Angular 4 路由器在我的应用程序中禁用直接浏览器导航?

Angular 无法做到这一点,因为这不是由 Angular 控制的。当您转到地址栏并输入地址然后按 Enter 时,浏览器会加载一个新页面。它可以是 Angular 应用程序,也可以是任何其他应用程序。这是一个浏览器功能。Angular 仅您单击routerLink.

您可以尝试使用onbeforeunload,但它有其局限性。

于 2017-08-01T04:29:10.237 回答