使用Angular关闭浏览器窗口/选项卡时执行异步服务获取 [英] Perform an asynchronous service get when closing browser window / tab with Angular

查看:337
本文介绍了使用Angular关闭浏览器窗口/选项卡时执行异步服务获取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用户试图离开我的页面时,我目前正在尝试使Angular应用程序进行API服务调用.关闭标签页/窗口,或输入外部URL.

I'm currently trying to make an Angular app make an API service call when the user tries to navigate away from my page. Either by closing the tab / window, or typing in an external URL.

我已尝试实现我在此处对stackoverflow问题所描述的几种不同方式,但是似乎都没有达到预期的效果.有人提到在Chrome上onbeforeunload中已经或正在弃用同步ajax请求.其他人建议使用似乎遭受同样命运的XMLHttpRequests. 我尝试使用 @HostListener('window:onbeforeunload', ['$event']),和HTML (window:beforeunload)="doBeforeUnload($event)"中的等效项,但所有人都拒绝合作.我可以显示console.logs,但是API从未收到任何注销用户的调用. 我还使用了navigator.sendBeacon,尽管其功能返回了true,表示作业已发送到浏览器队列,但没有实现.

I've tried to implement several different ways I've seen described here on stackoverflow questions, but none seem to have the desired effect. Some mention sync ajax requests which have been, or are in the process of being deprecated in onbeforeunload on Chrome. Others advise the use of XMLHttpRequests, which seem to have suffered the same fate. I have attempted the use of @HostListener('window:onbeforeunload', ['$event']), and equivalent in the HTML (window:beforeunload)="doBeforeUnload($event)", but all refuse to cooperate. I can get console.logs to show up, but the API never receives any call to logout the user. I have also used navigator.sendBeacon and, despite its function returning true, signalling that the job was sent to the browser queue, nothing ever materializes.

当前,注销功能是这样的:

Currently, the logout function is this:

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

这又是一个通用的http get函数:

Which, in turn, is a generic http get function:

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

使用HttpInterceptor添加完整的URL.注销功能本身正在工作,因为它在菜单选项中使用,当手动使用时,该菜单选项可以正常工作.因此功能应该不是问题.

The full url is added with the use of an HttpInterceptor. The logout function itself is working, as it is used in a menu option that works as expected when used manually. So the function should not be the problem.

我要做的就是以同步或异步方式调用userLogout函数,并通知后端用户已离开.

All I'm attempting to do is to call the userLogout function either in a sync or async way and inform the backend that the user has left.

推荐答案

经过一番修补,我最终基于此

After some tinkering, I ended up with a solution based on this answer, even though, for some reason, it didn't work for me on my first attempts.

我在组件中添加了以下HostBinding:

I added the following HostBinding to the component:

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

其中调用了一个简单的函数,该函数将使用身份验证服务注销方法.

Which calls a simple function that will use the authentication service logout method.

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

我必须创建一个单独的注销功能,以便它可以是同步的.还必须添加标题以进行后端授权,因为我的Http拦截器无法捕获XMLHttpRequest并将其自身添加.

I had to create a separate logout function, so that it could be synchronous. Headers also had to be added for backend authorization, as my Http interceptor was unable to catch the XMLHttpRequest and add them itself.

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

这篇关于使用Angular关闭浏览器窗口/选项卡时执行异步服务获取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆