Выполнить асинхронный сервис get при закрытии окна / вкладки браузера с Angular - PullRequest
2 голосов
/ 13 мая 2019

В настоящее время я пытаюсь заставить приложение Angular выполнять вызов службы API, когда пользователь пытается отойти от моей страницы.Либо закрыв вкладку / окно, либо набрав внешний URL-адрес.

Я пытался реализовать несколько различных способов, описанных здесь, в вопросах stackoverflow, но, похоже, ни один из них не дал желаемого эффекта.Некоторые упоминают о синхронизации запросов AJAX, которые были или находятся в процессе устаревания в onbeforeunload в Chrome.Другие советуют использовать XMLHttpRequests, которые, похоже, постигла та же участь.Я пытался использовать @HostListener('window:onbeforeunload', ['$event']) и эквивалент в HTML (window:beforeunload)="doBeforeUnload($event)", но все отказываются сотрудничать.Я могу получить console.logs для отображения, но API никогда не получает никакого вызова для выхода из системы пользователя.Я также использовал navigator.sendBeacon и, несмотря на то, что его функция возвращает true, сигнализируя о том, что задание было отправлено в очередь браузера, ничего не материализуется.

В настоящее время функция выхода из системы выглядит так:

userLogout(): Observable<any> {
    return this.apiService.get('/Account/Logout/');
  }

Это, в свою очередь, общая функция http get:

get<T>(url: string, options?: { params: HttpParams }): Observable<any> {
    return this.httpRequest<T>('get', url, null, options ? options.params : null);
  }

Полный URL-адрес добавляется с использованием HttpInterceptor.Сама функция выхода из системы работает, так как она используется в пункте меню, который работает, как ожидается, при использовании вручную.Таким образом, эта функция не должна быть проблемой.

Все, что я пытаюсь сделать, это вызвать функцию userLogout либо синхронно, либо асинхронно и сообщить бэкэнду, что пользователь ушел.

1 Ответ

0 голосов
/ 05 июня 2019

После некоторой переделки я получил решение, основанное на этом ответе , хотя по некоторым причинам оно не сработало для меня при моих первых попытках.

Iдобавил следующий компонент HostBinding к компоненту:

@HostListener('window:beforeunload', ['$event']) beforeunloadHandler(event) {
    this.pageClosed();
}

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

pageClosed() {
    this.authenticationService.userLogoutSync();
}

Мне пришлось создать отдельную функцию выхода из системы, поэтомучто это может быть синхронно.Заголовки также нужно было добавить для авторизации на сервере, так как мой перехватчик Http не смог перехватить XMLHttpRequest и добавить их сам.

const xhr = new XMLHttpRequest();
    xhr.open('GET', environment.backend + '/Account/Logout/', false);
    xhr.setRequestHeader('Authorization', 'Bearer ' + this.jwtService.getAccessToken());
    xhr.send();
}
...