页面关闭时通过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
相关产品推荐
相关产品推荐

