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

React/Next.js中页面刷新或标签关闭时如何在WebSocket关闭时发送数据

解决WebSocket页面刷新/关闭时发送离线状态的问题

你当前的代码存在一个关键问题:当页面刷新或标签页关闭时,WebSocket连接已经处于断开状态,此时在onclose回调里调用ws.send()会直接失败——因为连接已经不存在了。要实现页面卸载时的离线状态通知,得结合页面卸载事件和更可靠的发送方式来处理,具体方案如下:

核心思路

  1. 保留原有的onclose回调,处理意外断开连接的场景(比如网络中断);
  2. 监听页面的beforeunload事件,在页面卸载前主动发送离线状态,这里优先使用navigator.sendBeacon——它是浏览器专门为页面卸载场景设计的API,能保证请求在后台异步完成,不会阻塞页面关闭/刷新。

完整代码示例

const ws = new WebSocket('ws_url', 'token');
const userId = "someid";

// 处理意外断开连接的情况
ws.onclose = (e) => {
  // 仅当连接曾正常建立过,才尝试发送离线状态
  if (e.wasClean) {
    try {
      const offlineData = JSON.stringify({
        type: "offline",
        userId: userId
      });
      ws.send(offlineData);
    } catch (err) {
      console.error('离线状态发送失败:', err);
    }
  }
};

// 处理页面刷新/关闭的场景
window.addEventListener('beforeunload', () => {
  const offlineData = JSON.stringify({
    type: "offline",
    userId: userId
  });
  
  // 用sendBeacon发送到后端HTTP接口,可靠性更高
  navigator.sendBeacon('/your-offline-notify-endpoint', offlineData);

  // 若必须通过WebSocket发送,可尝试以下方式(但不如sendBeacon可靠)
  // if (ws.readyState === WebSocket.OPEN) {
  //   ws.send(offlineData);
  //   // 主动关闭连接
  //   ws.close(1000, '页面卸载');
  // }
});

关键说明

  • beforeunload事件会在页面卸载前触发,此时不能依赖普通异步请求(比如fetch),因为页面会直接终止异步任务;navigator.sendBeacon会让浏览器在后台完成请求,不受页面卸载影响。
  • 在onclose回调里判断e.wasClean,可以避免连接未成功建立就触发关闭事件时的无效发送操作。
  • 如果业务必须通过WebSocket发送离线状态,在beforeunload里要先检查连接状态(ws.readyState === WebSocket.OPEN),但这种方式仍可能因为页面卸载过快导致发送失败,所以优先推荐HTTP接口+sendBeacon的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:20:16