You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nuxt.js中如何在关闭/刷新应用前调用API?

在Nuxt 2/Vue 2中页面卸载前调用Firebase API的最佳方案

核心问题是页面卸载时,普通异步请求会被浏览器终止——beforeunload回调不会等待Promise完成。以下是两种可靠的解决方法:

方法1:使用navigator.sendBeacon()(推荐)

这是浏览器专门为页面卸载时的异步数据上报设计的API,会在后台异步发送请求,不阻塞页面卸载,兼容性良好。

代码示例

<template>
  <div>
    <h1>Page Firebase</h1>
  </div>
</template>

<script>
export default {
  methods: {
    trackUserAction() {
      // 组装要保存的用户行为数据
      const actionData = {
        userId: this.$fire.auth.currentUser?.uid,
        action: 'page_unload',
        timestamp: new Date().toISOString()
      };

      // 将JSON转为Blob(sendBeacon支持的格式)
      const blob = new Blob([JSON.stringify(actionData)], { type: 'application/json' });
      // 替换为你的Firebase REST端点(比如实时数据库或Firestore)
      const firebaseEndpoint = 'https://your-project-id.firebaseio.com/user-actions.json';

      // 发送请求,浏览器会确保请求完成
      navigator.sendBeacon(firebaseEndpoint, blob);
    }
  },

  mounted() {
    // 监听页面卸载事件
    window.addEventListener('beforeunload', this.trackUserAction);
  },

  beforeDestroy() {
    // 移除监听,避免内存泄漏
    window.removeEventListener('beforeunload', this.trackUserAction);
  }
};
</script>

注意事项

  • sendBeacon仅支持POST请求,且无法自定义请求头(如果需要认证,可将token拼接到URL参数中)
  • 若使用Firestore的REST API,需将数据转为Firestore要求的字段格式

方法2:使用带keepalive选项的fetch

如果需要自定义请求头(比如Firebase认证Token),可以用fetch并开启keepalive选项,浏览器会在页面卸载后继续完成请求。

代码示例

<template>
  <div>
    <h1>Page Firebase</h1>
  </div>
</template>

<script>
export default {
  methods: {
    async trackUserAction() {
      try {
        // 获取Firebase用户认证Token
        const token = await this.$fire.auth.currentUser?.getIdToken();
        if (!token) return;

        const actionData = {
          fields: {
            userId: { stringValue: this.$fire.auth.currentUser.uid },
            action: { stringValue: 'page_unload' },
            timestamp: { timestampValue: new Date().toISOString() }
          }
        };

        await fetch('https://firestore.googleapis.com/v1/projects/your-project-id/databases/(default)/documents/user-actions', {
          method: 'POST',
          body: JSON.stringify(actionData),
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${token}`
          },
          keepalive: true // 关键:让请求在页面卸载后继续执行
        });
      } catch (err) {
        console.error('上报用户行为失败:', err);
      }
    }
  },

  mounted() {
    window.addEventListener('beforeunload', this.trackUserAction);
  },

  beforeDestroy() {
    window.removeEventListener('beforeunload', this.trackUserAction);
  }
};
</script>

额外说明

  • 不要依赖beforeDestroy处理页面刷新/关闭:该钩子仅在Vue组件销毁(比如页面切换)时触发,页面刷新或浏览器关闭时不会执行
  • 若需处理页面切换时的行为上报,可结合Nuxt的page:leave钩子,直接调用异步API即可(无需担心请求被终止)

内容的提问来源于stack exchange,提问作者vanminhquangtri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 02:35:35