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

页面关闭时通过AJAX/sendBeacon执行MySQL查询失败求助

解决页面卸载时执行MySQL查询的问题

先拆解两种方法失效的原因:

  • 同步AJAX失效:现代浏览器(Chrome、Firefox等)在页面卸载阶段会直接取消同步XMLHttpRequest请求,哪怕设置了async: false,浏览器不会等待请求完成就关闭页面,导致后端收不到请求。
  • sendBeacon失效:你的Blob构造写法错误,正确的Blob第一个参数必须是数组形式;另外sendBeacon发送JSON时,后端若未正确处理非application/x-www-form-urlencoded类型的请求体,会导致解析失败。

修正方案1:正确使用sendBeacon(推荐)

调整Blob创建逻辑,同时适配后端的JSON解析:

window.onbeforeunload = function(e) {
  // 修正Blob构造:第一个参数为数组,第二个为配置对象
  const blob = new Blob([JSON.stringify(selectedSeats)], { type: 'application/json' });
  navigator.sendBeacon('release_all_holds.php', blob);
};

后端(release_all_holds.php)适配代码:
PHP默认不会自动解析JSON请求体,需手动读取原始请求数据:

// 读取原始请求内容
$rawData = file_get_contents('php://input');
$seats = json_decode($rawData, true);

// 执行MySQL释放座位的逻辑(示例)
if (!empty($seats)) {
  $placeholders = implode(',', array_fill(0, count($seats), '?'));
  // 假设你已建立数据库连接$conn
  $stmt = $conn->prepare("UPDATE seats SET hold_status = 0 WHERE id IN ($placeholders)");
  $stmt->execute($seats);
}

修正方案2:使用fetch的keepalive选项

若sendBeacon仍有问题,可改用fetch的keepalive参数,它支持更多请求配置,兼容性也不错:

window.onbeforeunload = function(e) {
  fetch('release_all_holds.php', {
    method: 'POST',
    body: JSON.stringify(selectedSeats),
    headers: {
      'Content-Type': 'application/json'
    },
    keepalive: true, // 核心:让请求在页面卸载后继续完成
    credentials: 'include' // 若需要携带会话Cookie验证,加上此配置
  });
};

后端处理逻辑和上述PHP代码一致,读取php://input解析JSON即可。

额外注意点

  • 卸载事件中只做最轻量的请求,避免复杂逻辑拖慢请求完成速度;
  • 测试时可通过window.close()或刷新页面验证,部分浏览器在开发者工具开启时会有特殊行为;
  • 若涉及权限验证,确保请求携带了必要的会话信息(如Cookie),避免后端因未授权拒绝执行查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 06:12:21