React中如何实现关闭浏览器时触发调用API接口
可行解决方案
你可以通过监听beforeunload浏览器事件来实现这个需求,这个事件会在浏览器窗口即将关闭、刷新页面、导航离开当前站点的时候触发,刚好覆盖你说的关闭浏览器的场景。
类组件实现方案
- 在
componentDidMount生命周期中绑定beforeunload事件监听 - 在事件回调里执行你的API请求,这里要注意:普通异步请求在页面销毁过程中大概率会被浏览器中断,所以优先用
Navigator.sendBeacon()方法来发送请求,这个API是浏览器专门设计用来在页面卸载阶段发送异步请求的,会保证请求能被正常发出,不会随页面销毁被中断 - 在
componentWillUnmount里移除事件监听,避免内存泄漏
代码示例:
class YourTableComponent extends React.Component { componentDidMount() { window.addEventListener('beforeunload', this.handleBeforeUnload); } componentWillUnmount() { // 正常路由跳转离开的场景保留原有逻辑,和beforeunload形成双兜底 this.saveColumnWidth(); window.removeEventListener('beforeunload', this.handleBeforeUnload); } handleBeforeUnload = () => { const columnWidthData = this.getColumnWidth(); // 替换为你自己的获取列宽逻辑 // 用sendBeacon发送请求,JSON格式数据需要转成Blob对象 const data = new Blob([JSON.stringify(columnWidthData)], { type: 'application/json' }); navigator.sendBeacon('/api/save-column-width', data); } // 其余业务逻辑省略 }
函数组件实现方案
如果使用函数组件+Hooks写法,可以用useEffect完成事件的绑定和解绑:
const YourTableComponent = () => { useEffect(() => { const handleBeforeUnload = () => { const columnWidthData = getColumnWidth(); // 替换为你自己的获取列宽逻辑 const data = new Blob([JSON.stringify(columnWidthData)], { type: 'application/json' }); navigator.sendBeacon('/api/save-column-width', data); }; window.addEventListener('beforeunload', handleBeforeUnload); return () => { saveColumnWidth(); // 原有的路由跳转离开时的保存逻辑 window.removeEventListener('beforeunload', handleBeforeUnload); }; }, []); // 其余业务逻辑省略 }
注意事项
- 部分浏览器下
beforeunload事件里不允许执行同步阻塞操作,比如alert、confirm,也不推荐用同步XHR,会被浏览器拦截或者影响用户体验,强制优先用navigator.sendBeacon - 如果你的接口要求自定义请求头,比如鉴权的Authorization头,sendBeacon暂不支持自定义请求头,这种情况可以把参数拼到URL的query里,或者改用FormData格式传参,后端对应调整解析逻辑即可
- 这个事件触发的前提是用户正常关闭浏览器,如果是浏览器崩溃、设备强制断电等极端场景还是没法触发,这个属于浏览器层面的限制,暂无通用解决方案
内容的提问来源于stack exchange,提问作者grit-ki
相关产品推荐
相关产品推荐

