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

寻求用户关闭浏览器/标签页时调用API的可靠方案(含React相关)

可行解决方案:使用navigator.sendBeacon()

现代浏览器对unload事件中的异步请求有严格限制,容易被中断,而navigator.sendBeacon()是浏览器专门为页面卸载时发送请求设计的API,它会将请求加入后台发送队列,保证页面卸载过程中请求能完成发送,不会被浏览器取消。

原生JavaScript实现

// 监听beforeunload事件(触发于窗口/标签关闭、刷新前)
window.addEventListener('beforeunload', (event) => {
  // 可选:触发浏览器的关闭确认提示(如需拦截误操作可保留,不需要则删除)
  event.preventDefault();
  event.returnValue = '';

  // 构造请求数据(支持FormData、Blob、字符串等格式)
  const requestData = new FormData();
  requestData.append('userId', '你的用户ID');
  requestData.append('action', 'session_terminated');

  // 发送API请求
  if (navigator.sendBeacon) {
    // 优先使用sendBeacon
    navigator.sendBeacon('/your-api-endpoint', requestData);
  } else {
    // 兼容旧浏览器的降级方案(同步XHR,会阻塞页面卸载,仅作备选)
    const xhr = new XMLHttpRequest();
    xhr.open('POST', '/your-api-endpoint', false);
    xhr.send(requestData);
  }
});

React组件中实现

import { useEffect } from 'react';

function YourComponent() {
  useEffect(() => {
    const handlePageUnload = (event) => {
      // 可选:触发关闭确认提示
      event.preventDefault();
      event.returnValue = '';

      const requestData = new FormData();
      requestData.append('userId', '你的用户ID');
      requestData.append('action', 'session_terminated');

      if (navigator.sendBeacon) {
        navigator.sendBeacon('/your-api-endpoint', requestData);
      }
    };

    // 添加事件监听
    window.addEventListener('beforeunload', handlePageUnload);

    // 组件卸载时移除监听
    return () => {
      window.removeEventListener('beforeunload', handlePageUnload);
    };
  }, []);

  return <div>你的组件内容</div>;
}

export default YourComponent;

进阶:带自定义请求头的场景

如果API需要自定义请求头(如Content-Type: application/json),可以使用fetch并开启keepalive选项:

window.addEventListener('pagehide', async () => {
  const payload = JSON.stringify({
    userId: '你的用户ID',
    action: 'session_terminated'
  });

  await fetch('/your-api-endpoint', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: payload,
    keepalive: true // 关键:启用keepalive保证请求完成
  });
});

注意事项

  • sendBeacon仅支持POST请求,无法自定义请求头,适合简单表单或字符串数据传输
  • 避免使用unload事件,优先选择beforeunload或pagehide作为触发时机
  • 同步XHR会阻塞页面卸载流程,影响用户体验,仅作为老旧浏览器的降级方案
  • 后端需确保能正确解析sendBeacon或keepalive请求的数据格式(如FormData或JSON)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 17:17:32