使用 beforeunload 在 window 上发送信标的正确方法使用 angular 关闭 13

proper way of using beforeunload to send a beacon on window close using angular 13

我试图在用户关闭浏览器时发送信标 window 他们正在我的网站上查看。我正在使用 Angular 13 并使用 window 和导航器 javascript api 来完成它。

首先我知道在我的 init post 中疯狂地回调。它会得到修复只是我现在不关心的事情。

ngOnInit(): void {
    window.scrollTo(0,0);
    this.route.params
      .subscribe(
        (params: Params)=>{
          this.creatorslug = params['creatorslug'];
          this.userobject = this.authservice.getUser$()
            .subscribe(
              (object : any)=>{
                this.userobject = object;
                this.http.get(environment.add_user_to_content_creator_shochat_stream + this.creatorslug)
                  .subscribe(
                    (req: any)=> {
                      this.shochatobject = req;
                      window.addEventListener('beforeunload', ev => {
                        const payload = {
                          shochatid: this.shochatobject['shochatid']
                        };
                        if(!this.properleave){
                          //@ts-ignore
                          navigator.sendBeacon(environment.receive_beacon_user_leave_shochat, payload)
                        }

                        });
                      this.loaded = true;
                      this.syncsubscription = this.tss.receiveSyncClient()
                        .subscribe(
                          (req: any) => {
                            if(req != null){
                              this.syncClient = req;
                              this.syncClient.document(this.tss.setdocumentname(this.shochatobject['contentcreatordisplayname'])).then((doc) => {
                                if(doc.data.killshochat){
                                  this.leaveshochat();
                                }
                              });

                              this.syncClient.document(this.tss.setdocumentname(this.shochatobject['contentcreatordisplayname'])).then((doc)=>{
                                doc.on('updated', (event)=>{
                                  if(event.data.killshochat){
                                    this.leaveshochat();
                                  }
                                });
                              });
                            }

                          });
                    });
              });
        });
  }

关于我分享的组件init函数的通知我定义了beforeunload监听器

window.addEventListener('beforeunload', ev => {
                            const payload = {
                              shochatid: this.shochatobject['shochatid']
                            };
                            if(!this.properleave){
                              //@ts-ignore
                              navigator.sendBeacon(environment.receive_beacon_user_leave_shochat, payload)

正确的离开布尔值与用户正确离开页面时调用的标志有关。

leaveshochat(){
    this.properleave = true;
    // @ts-ignore
    const url = environment.user_leave_shochat + this.shochatobject.shochatid;
    this.http.delete(url)
      .subscribe(
        (req: any)=>{
          // @ts-ignore
          this.router.navigate(['user-services', 'user-shochat-end', this.shochatobject.shochatid]);
        });
  }

但是当我测试关闭浏览器 window 而没有单击使用信标不发送的 leaveshochat() 功能的按钮时会发生什么。我想我在做一些愚蠢的事情。

update 我读了这篇文章,然后尝试了这个,但仍然没有任何变化

@HostListener('window:beforeunload',['$event'])

  unloadHandler(event: Event){
    const payload = {
      shochatid: this.shochatobject['shochatid']
    };
    if(!this.properleave){
      //@ts-ignore
      navigator.sendBeacon(environment.receive_beacon_user_leave_shochat, payload)
    }
  }

假设这个问题不是来自移动设备?例如,在以下情况下不会触发这些事件:

  1. 用户加载页面并与之交互。
  2. 完成后,他们会切换到其他应用,而不是关闭标签页。
  3. 之后,他们使用 phone 的应用程序管理器关闭了浏览器应用程序。

我在这里没有看到的另一件事是 this.properleave 是什么?您确定用户离开时它处于正确状态吗?无论如何,我尝试对其进行测试,并且能够在卸载之前 post 消息内容。

  ngOnInit() {
    this.subscribeToNativeNavigation();
  }

  private subscribeToNativeNavigation() {
    fromEvent(window, 'beforeunload')
    .subscribe((e) => {
      const message = 'Sending data';
      (e || window.event).returnValue = !message;
      console.log(message)
      navigator.sendBeacon('/log', message);
      return message;
    })
  }

  refreshPage() {
    location.reload();
  }

示例:https://stackblitz.com/edit/beforeunload-warning-kmbxjl?file=src%2Fapp%2Fapp.component.ts