Запретить пользователю навигацию, введя URL-адрес вручную - PullRequest
0 голосов
/ 17 марта 2020

Я работаю над приложением с реактивными формами, где пользователь заполняет данные и переходит к следующему шагу, нажимая кнопку Далее.
У меня есть следующая проблема, которую нужно решить в моем приложении: пользователь не может перемещаться по сайт, вручную изменив URL. Если он / она пытается, ожидаемый результат должен быть:

  1. Всплывающее окно с информацией о том, что все данные будут потеряны, и пользователь будет возвращен на первую страницу.

  2. После того, как пользователь изменит URL-адрес и примет потерю данных, нажав «Да», пользователь должен начать с первой страницы.

  3. Единственный раз, когда пользователь должен оставаться на той же странице должно быть после обновления страницы.

Сначала я попытался сделать это с помощью охранников, но потом я не смог найти способ Angular сказать, что защита должна работать, только если пользователь изменяет URL-адрес вручную. Охранник также работал во время навигации с помощью кнопки Next - другими словами, кнопка Next больше не позволяла мне go перейти к следующему шагу.

Затем я реализовал что-то вроде этого:

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;
    }
}

и добавил эту защиту для каждого из моих путей, и она работала довольно хорошо, пока я не понял, что это решение также не идеально, потому что оно перенаправляет меня на первую страницу после обновления страницы. Также попробовал CanDeactivate, но я думаю, это не то, что мне нужно здесь. Есть идеи?

1 Ответ

0 голосов
/ 19 марта 2020

Angular охранники не могут запретить браузеру выполнять собственные действия по навигации (см. sh, ручное изменение URL, закрытие вкладки и т. Д. c). Как правило, вы хотите использовать средства защиты и всплывающие окна внутри приложения, предотвращающие навигацию на основе Angular, такую ​​как router.navigate() и [routerLink], но вам придется использовать стандартные методы для обработки собственных действий.

Вы можете использовать перед загрузкой , чтобы справиться с этим резервом. Примечание: как уже упоминалось в этом ответе SO , Chromium не позволит вам ввести пользовательское сообщение , но вы можете go выполнить шаги для других браузеров.

Вот Stackblitz , показывающий это в действии, но вот суть. Вы можете создать Observable из собственного события window.beforeunload, отфильтровать результаты, чтобы оно срабатывало только тогда, когда это необходимо (например, this.warn изменится на любое логическое значение или выражение, которое вы хотите проверить), затем подпишитесь на него и установите свой возврат значения как ниже:

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;
  });
...