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

在Python Flask中实现带百分比的响应式进度条,无法获取处理进度

Flask + JS 实现后台处理进度条解决方案

问题分析

你当前的代码无法获取后台处理进度的核心原因:

  • XHR的progress事件仅监听HTTP请求的传输进度(上传/下载字节的进度),但后台的耗时处理是在服务器端执行的,此时HTTP响应还未开始返回,前端无法捕获中间进度。
  • Flask默认是完成所有业务逻辑后才返回完整响应,不会实时推送处理进度。

解决方案:使用定时轮询+后台线程实现实时进度推送

通过后台线程执行耗时任务,同时提供进度查询接口,前端定时获取进度并更新UI,是实现这类需求的简单可靠方案。

1. 修正后端Flask代码

from flask import Flask, render_template, jsonify, session
import time
import threading
import uuid

app = Flask(__name__)
app.secret_key = 'your-secure-secret-key'  # 生产环境请使用安全密钥

# 模拟耗时处理任务,实时更新进度
def long_running_task(task_id):
    # 替换为你的实际处理逻辑:请求外部接口、读取处理数据等
    total_steps = 10
    for step in range(total_steps):
        time.sleep(1)
        # 更新进度到session(生产环境建议用Redis等分布式存储,避免多线程冲突)
        session[f'progress_{task_id}'] = (step + 1) * 10
        session.permanent = True

@app.route('/test')
def testindex():
    return render_template('layouts/loading.html')

@app.route('/start_process')
def start_process():
    # 生成唯一任务ID,避免多用户进度冲突
    task_id = str(uuid.uuid4())
    # 启动线程执行耗时任务,不阻塞Flask主线程
    threading.Thread(target=long_running_task, args=(task_id,)).start()
    return jsonify({'task_id': task_id})

@app.route('/get_progress/<task_id>')
def get_progress(task_id):
    # 返回当前任务进度,默认0
    progress = session.get(f'progress_{task_id}', 0)
    return jsonify({'progress': progress})

2. 修正前端HTML/JS代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Loading Progress Bar</title>
    <style>
        #progress-bar {
            width: 100%;
            background-color: #f3f3f3;
        }
        #progress {
            width: 0%;
            height: 30px;
            background-color: #4caf50;
            text-align: center;
            line-height: 30px;
            color: white;
            transition: width 0.3s ease;
        }
    </style>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
    <div id="progress-bar">
        <div id="progress">0%</div>
    </div>
    <br>
    <button onclick="startProcess()">Start Process</button>

    <script>
        function startProcess() {
            const progressBar = document.getElementById('progress');
            // 重置进度条状态
            progressBar.style.width = '0%';
            progressBar.textContent = '0%';

            // 启动后台任务
            $.get('/start_process', function(res) {
                const taskId = res.task_id;
                // 定时轮询获取进度
                const pollInterval = setInterval(() => {
                    $.get(`/get_progress/${taskId}`, function(progressRes) {
                        const currentProgress = progressRes.progress;
                        // 更新UI
                        progressBar.style.width = `${currentProgress}%`;
                        progressBar.textContent = `${currentProgress}%`;
                        
                        // 进度完成后停止轮询
                        if (currentProgress >= 100) {
                            clearInterval(pollInterval);
                            alert('处理完成!');
                        }
                    });
                }, 500); // 每500ms查询一次,可根据需求调整
            });
        }
    </script>
</body>
</html>

关键注意事项

  • 后端必须用线程执行耗时任务,否则Flask主线程会被阻塞,无法响应后续的进度查询请求。
  • 进度存储:示例用Flask Session,生产环境建议用Redis等分布式存储,避免多进程/多线程环境下的进度共享问题。
  • 前端轮询间隔:根据处理任务的耗时调整,间隔太小会增加服务器压力,太大则进度更新不及时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 23:05:54