我正在使用HostListener来检测用户何时重新加载或关闭浏览器窗口。目的是#1检查当前用户是否对记录拥有“正在编辑中”锁,而#2如果是,则调用一个可观察对象以更新数据库。 (注意:我已经实现了锁定系统,可以使用CanDeactivate导航离开组件。使用HostListener专门用于重新加载或关闭浏览器窗口。)
根据此similar question,'window:unload'
是仅同步事件,因此我不能在主机侦听器的主体中使用异步API调用。
但是,使用XMLHttpRequest()
的公认解决方案是being deprecated according to Mozilla.
注意:从Gecko 30.0(Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27),Blink 39.0和Edge 13上的同步请求 主线程由于对线程的负面影响而被弃用 用户体验。
我需要一个更可靠的解决方案。有没有一种方法可以在Angular中发送SYNCHRON API来解决此限制?还是有另一种方法可以确保在重新加载或关闭浏览器之前完成API调用?
// @HostListener allows guard against browser refresh, close, etc.
@HostListener('window:unload', ['$event'])
beforeUnloadHander($event) {
// Check if Is Being Edited must be removed
if (this.mustReleaseIsBeingEdited()) {
this.updateIsBeingEditedSub = this.updateIsBeingEdited$(true).subscribe(result => {
return true;
}, err => { console.error(err); }, () => { });
} else {
return true;
}
}
private updateIsBeingEdited$(isBeingEdited): Observable<boolean> {
const editedObj = {
_id: this.record._id,
IsBeingEdited: isBeingEdited,
EditedBy: this.accessLevelService.getUserId()
}
return this.httpService!.postData(
`records/_id/${editedObj._id}/IsBeingEdited/`,
editedObj
);
}
更新
我正在研究,可能已经找到了possible solution with sendBeacon()。我不确定如何在Angular中实现此功能,或者是否建议这样做。有什么建议吗?
为解决此问题,分析和诊断代码具有 历史上在卸载时进行了同步XMLHttpRequest调用,或者 beforeunload事件处理程序提交数据。同步 XMLHttpRequest阻止了文档的卸载过程, 转弯会导致下一个导航速度变慢。
这是sendBeacon()出现的地方。通过使用sendBeacon()方法, 用户将数据异步传输到Web服务器 代理商有机会这样做,而不会延迟卸载或 影响下一个导航的性能。这解决了所有 提交分析数据的问题:数据已发送 可靠地,它是异步发送的,并且不会影响加载 的下一页。
答案 0 :(得分:1)
使用sendBeacon()方法,将传输数据 当用户代理具有一个 这样做的机会,而不会延迟卸载或影响 下一次导航的效果。
第二种可能的解决方法是将keepalive
设置为true的send the request via the fetch API。
这是我用sendBeacon()测试过的解决方案。
@HostListener('window:beforeunload', ['$event'])
onBeforeUnload(): void {
/**
* Post a single object to the server
* Send Beacon API to keep request after browser windowunload event
*/
navigator.sendBeacon(`${this.env.apiUrl}/id/${this.id}`);
}