当用户试图离开我的页面时,我目前正在尝试使Angular应用程序进行API服务调用。关闭标签页/窗口,或输入外部URL。
我已尝试实现我在此处介绍的关于stackoverflow问题的几种不同方式,但是似乎没有一种方法具有预期的效果。有人提到在Chrome上onbeforeunload中已经或正在弃用同步ajax请求。其他人建议使用似乎遭受同样命运的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);
}
使用HttpInterceptor添加完整的URL。注销功能本身正在工作,因为它在菜单选项中使用,手动使用时可以按预期工作。因此功能应该不是问题。
我要做的就是以同步或异步方式调用userLogout函数,并通知后端用户已离开。
答案 0 :(得分:1)
对于我来说,async/await
非常适合在关闭浏览器标签/更改标签网址的同时拨打http。
@HostListener('window:beforeunload', ['$event'])
async beforeunloadHandler(event) {
await triggerSyncLogout();
}
async triggerSyncLogout(){
let url = 'www.sample.com';
let reqHeaders = new HttpHeaders().append('Authorization', token).append('Accept', 'application/json');
const options = {
headers: reqHeaders,
withCredentials: true,
observe: 'response' as 'response'
}
return await this.http.get<any>(url, options).toPromise();
}
答案 1 :(得分:0)
经过一番修补,我最终基于answer得到了一个解决方案,尽管由于某种原因,它对我的初次尝试没有用。
我在组件中添加了以下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();
}