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

页面刷新时向Flask服务器发送通知的问题求助

问题分析与解决方案

问题原因

刷新页面或调用location.reload()时,beforeunload事件虽然会触发,但你用的普通异步fetch请求会被浏览器终止——因为刷新时浏览器会立即启动新页面的加载,优先释放旧页面的资源,未完成的异步请求会被直接取消。而关闭标签页时,浏览器没有后续页面加载任务,会给异步请求留出完成时间,所以能正常发送。

另外,Firefox v102.15.1这类旧版本对beforeunload中的异步操作有更严格的生命周期限制,进一步导致刷新场景下请求失败。

解决方法

要确保卸载前的请求能被服务器接收,必须使用浏览器专门为这类场景设计的API,推荐两种方案:

方案1:使用navigator.sendBeacon()

这是最可靠的方式,浏览器会保证请求在后台完成,不受页面卸载的影响:

function send_msg() {
  // 构造要发送的JSON数据
  const payload = JSON.stringify({ action: 'page_unload', timestamp: Date.now() });
  // 发送请求,sendBeacon默认用POST方法,数据会以text/plain发送
  navigator.sendBeacon('/notify-unload', payload);
}

window.addEventListener('beforeunload', function() {
  send_msg();
});

方案2:带keepalive选项的fetch

如果需要自定义请求方法、头部等,可以给fetch加上keepalive: true选项,让浏览器保留请求直到完成:

function send_msg() {
  const payload = JSON.stringify({ action: 'page_unload', timestamp: Date.now() });
  fetch('/notify-unload', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: payload,
    keepalive: true // 关键配置,确保请求不被终止
  });
}

window.addEventListener('beforeunload', function() {
  send_msg();
});

Flask后端适配

注意sendBeacon默认发送的Content-Type是text/plain,如果发送JSON,后端需要正确解析:

from flask import Flask, request, json
import json

app = Flask(__name__)

@app.route('/notify-unload', methods=['POST'])
def handle_unload_notification():
    # 解析请求数据
    if request.is_json:
        data = request.get_json()
    else:
        data = json.loads(request.data.decode('utf-8'))
    
    # 将数据写入JSON文件
    with open('unload_logs.json', 'a') as f:
        json.dump(data, f)
        f.write('\n')
    
    # 返回204无内容状态码,无需响应体
    return '', 204

if __name__ == '__main__':
    app.run(debug=True)

关于location.reload()的触发问题

调用location.reload()时,页面卸载流程比正常刷新更紧凑,普通异步请求几乎没有时间完成。而sendBeacon或带keepalive的fetch会让浏览器将请求标记为“必须完成”,即使页面已经开始卸载,也会在后台继续处理请求,因此能正常触发并发送通知。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 22:03:16