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

JavaScript如何在浏览器关闭时正确保存数据到MySQL数据库?

问题根因

onunload事件触发时,浏览器会直接终止页面所有待执行的异步请求、销毁页面进程,你使用的常规异步AJAX请求还没完成发送就被中断了。断点调试时进程被临时暂停,才有足够时间走完请求流程,所以只有调试时能保存成功。


可行解决方案

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

这是W3C专门为页面卸载阶段发送数据设计的API,浏览器会在后台异步完成请求,不阻塞页面关闭流程,且会尽可能保证请求发送成功。
修改后的代码如下:

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<h1>Testing data save on close event</h1>
    
</body>
</html>
<script>
window.onunload = function(e) {
        console.log("The Window is closing!");
        saveDataOnClose();
};
    
function saveDataOnClose(){
  const url = URL+"savedata.php";
  const client = [{firstName: 'John', lastName: 'doe', EmailAddress: 'jhon@gmail.com'}];
  const jObj = JSON.stringify(client);
  // 构造FormData方便PHP直接通过$_POST接收参数
  const formData = new FormData();
  formData.append('Client', jObj);
  // 发送beacon请求
  navigator.sendBeacon(url, formData);
}
</script>

后端PHP接口无需修改,直接和之前一样通过$_POST['Client']即可拿到数据。

方案2:使用带keepalive参数的Fetch API

和sendBeacon逻辑类似,通过keepalive参数告知浏览器页面关闭后也要继续完成请求:

function saveDataOnClose(){
  const url = URL + "savedata.php";
  const client = [{firstName: 'John', lastName: 'doe', EmailAddress: 'jhon@gmail.com'}];
  const formData = new FormData();
  formData.append('Client', JSON.stringify(client));
  
  fetch(url, {
    method: 'POST',
    body: formData,
    keepalive: true
  });
}

注意事项

  • 不要使用同步AJAX(给$.ajax加async: false参数),目前主流浏览器已经在unload、beforeunload事件中禁用了同步XHR请求,添加后也不会生效,还会触发控制台警告。
  • sendBeacon和带keepalive的fetch都有单请求数据大小限制,一般为64KB,存储常规用户操作数据完全够用,超出限制请求会发送失败。
  • 页面卸载后请求的成功/失败回调都不会执行,不要依赖回调做后续逻辑,后端接口要做好幂等处理,避免重复提交产生脏数据。
  • 如果需要给用户弹出是否保存的确认提示,可以搭配onbeforeunload事件使用,用户确认关闭后再触发数据保存逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 03:15:01