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
相关产品推荐
相关产品推荐

