如何在Flask执行send_from_directory时展示加载提示或动画
方案说明
浏览器的下载确认弹窗是原生控件,BOM没有权限监听其触发、操作、关闭事件,不用在这个方向尝试。下面是两种可直接落地的实现方案:
方案1:Cookie监听法(改造成本最低,推荐当前场景使用)
原理是后端文件生成完成、返回下载响应时携带自定义Cookie,前端轮询Cookie状态,检测到对应Cookie即判定文件已准备完成,直接关闭加载模态框。
后端修改(Flask侧)
在原有返回下载的逻辑外,用make_response包裹响应,新增自定义Cookie标记:
from flask import make_response @bp.route('/download', methods=['GET']) @login_required def download(backup=False): # 原有业务逻辑完全不变 # ... 省略拉取Spotify数据、生成CSV的代码 ... # 改造返回逻辑,新增Cookie resp = make_response(send_from_directory( temp_dir, target[0], as_attachment=True, attachment_filename=file_name )) # 自定义下载就绪标记Cookie,有效期1分钟,避免残留影响下次操作 resp.set_cookie('download_ready', '1', max_age=60) return resp
前端JS修改
下载按钮绑定点击事件,弹出加载框后启动定时器轮询Cookie:
document.querySelector('#download-btn').addEventListener('click', () => { // 先清除上次残留的Cookie document.cookie = "download_ready=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; // 打开加载模态框 openModal(); // 每500ms轮询一次Cookie状态 const checkTimer = setInterval(() => { if (document.cookie.includes('download_ready=1')) { // 清除定时器 clearInterval(checkTimer); // 关闭加载模态框 closeModal(); // 清空本次Cookie document.cookie = "download_ready=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; } }, 500); // 触发下载请求 window.location.href = '/download'; });
这个方案不需要改动原有业务逻辑,几行代码就能实现需求,兼容性覆盖所有主流浏览器。
方案2:异步任务+轮询(适合并发量高的场景)
如果站点访问量大,不想让长耗时请求占住服务连接,可以把CSV生成逻辑改为异步处理:
- 新增任务提交接口:前端点击下载后先调用该接口,后端立刻返回唯一任务ID,同时把生成CSV的逻辑放到后台异步执行(可用Celery、Flask执行器等工具实现)
- 新增任务状态查询接口:前端拿到任务ID后弹出加载框,定时调用该接口查询任务进度
- 检测到任务执行完成后,前端关闭加载框,再请求原下载地址获取生成好的CSV文件
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

