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

Flask下载中断检测:如何在用户取消下载时触发自定义函数?

Flask流式下载中捕获连接中断/取消事件的处理方法

当用户取消下载或连接中断时,Flask默认不会主动触发自定义逻辑,需要通过包装生成器并捕获相关异常来实现。以下是具体实现方案:

自定义带中断回调的生成器

先定义一个包装函数,在迭代响应内容时捕获连接异常,并触发自定义回调:

from flask import Response, stream_with_context
import requests

def stream_with_callback(response, chunk_size=2048, on_interrupt=None):
    try:
        # 迭代流式响应内容
        for chunk in response.iter_content(chunk_size=chunk_size):
            yield chunk
    except (IOError, BrokenPipeError, ConnectionResetError) as e:
        # 触发自定义中断处理函数
        if on_interrupt:
            on_interrupt()
        # 重新抛出异常,让WSGI服务器正确处理连接关闭
        raise

在API中使用该生成器

编写你的自定义中断处理函数,替换原有的流式响应逻辑:

def handle_download_interrupt():
    # 这里编写你的自定义逻辑,比如:
    # - 记录用户取消下载的日志
    # - 清理临时资源
    # - 通知后端服务停止相关任务
    print("检测到下载中断:用户取消或连接断开")

# 原API逻辑修改
@app.route('/download')
def download():
    url = "你的数据源URL"
    ssl_context = "你的SSL配置"
    headers = {"Content-Type": "application/octet-stream"}
    
    r = requests.get(url, stream=True, timeout=180, verify=ssl_context)
    # 使用自定义生成器包装响应流
    return Response(
        stream_with_context(stream_with_callback(r, on_interrupt=handle_download_interrupt)),
        headers=headers
    )

关键说明

  • 不同WSGI服务器(如uWSGI、Gunicorn)抛出的连接异常类型可能略有差异,IOError、BrokenPipeError、ConnectionResetError是最常见的几种,可根据实际日志补充异常类型。
  • 捕获异常后重新抛出是为了让服务器正确处理连接关闭流程,避免资源泄漏。
  • 如果需要主动关闭requests的连接,可在handle_download_interrupt中调用r.close(),不过正常迭代结束后requests会自动关闭连接,异常场景下手动关闭更稳妥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 00:22:10