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

Flask中Python脚本执行时如何传值给JS函数更新进度条

实时进度更新实现方案

普通的Flask视图函数会等所有逻辑执行完毕才一次性返回响应给前端,没法中途推送进度数据,用SSE(服务器发送事件) 就能实现你要的效果,比WebSocket轻量很多,不需要额外安装依赖,新手很容易跑通。

后端(views.py)改造

把原来的单一视图拆成两个:一个负责返回渲染好的主页,一个专门执行长任务、向前端流式推送进度值。

from flask import Flask, render_template, Response
import time  # 仅用于模拟耗时任务,实际使用可删除

app = Flask(__name__)

# 主页路由,仅负责返回页面
@app.route('/')
def home():
    return render_template("home.html")

# 长任务+进度推送接口,SSE专用
@app.route('/run-tasks')
def run_tasks():
    def generate_progress():
        # 把所有待执行任务按顺序放进列表,方便统计总进度
        tasks = [
            # 任务1:计算list1总和
            lambda: (
                sum([1, 2, 3, 4, 5])
            ),
            # 任务2:计算list2总和
            lambda: (
                sum([10, 20, 30, 40, 50])
            ),
            # 剩余任务按顺序往后追加即可,以下为模拟耗时任务示例
            lambda: time.sleep(1),
            lambda: time.sleep(1),
            lambda: time.sleep(1),
        ]
        total_task_num = len(tasks)
        # 逐个执行任务,每完成一个就推送一次进度
        for index, task in enumerate(tasks):
            task()  # 执行当前任务
            current_progress = int((index + 1) / total_task_num * 100)
            # SSE固定消息格式:必须以data:开头,结尾加两个换行符
            yield f"data:{current_progress}\n\n"
        # 所有任务完成推送100%进度
        yield "data:100\n\n"

    # 返回流式响应,必须指定Content-Type为text/event-stream
    return Response(generate_progress(), mimetype='text/event-stream')

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

你原来写的for循环累加逻辑完全可以保留,直接替换对应lambda里的sum代码就行,不影响进度推送。


前端(home.html)改造

保留你已经写好的updateProgressBar函数,新增SSE连接逻辑,收到后端推送的进度值就更新进度条即可。以下是完整可运行的示例,包含进度条基础样式:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>任务执行进度</title>
    <style>
        /* 进度条样式可根据需求自行修改 */
        .progress {
            width: 600px;
            height: 32px;
            border-radius: 16px;
            background: #f0f0f0;
            margin: 100px auto;
            position: relative;
            overflow: hidden;
        }
        .progress__fill {
            height: 100%;
            width: 0%;
            background: #2563eb;
            transition: width 0.2s ease;
        }
        .progress__text {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            margin: 0;
            font-size: 14px;
            color: #1f2937;
        }
    </style>
</head>
<body>
    <!-- 进度条DOM结构 -->
    <div class="progress">
        <div class="progress__fill"></div>
        <p class="progress__text">0%</p>
    </div>

    <script>
        // 你原有写好的进度条更新函数,无需修改
        function updateProgressBar(progressBar, value) {
            value = Math.round(value);
            progressBar.querySelector(".progress__fill").style.width = `${value}%`;
            progressBar.querySelector(".progress__text").textContent = `${value}%`;
        }

        // 页面加载完成后建立SSE连接
        document.addEventListener('DOMContentLoaded', () => {
            const progressBarEl = document.querySelector('.progress');
            // 连接后端的进度推送接口
            const sseClient = new EventSource('/run-tasks');

            // 收到后端推送的进度数据时触发更新
            sseClient.onmessage = (event) => {
                const progressVal = parseInt(event.data);
                updateProgressBar(progressBarEl, progressVal);
                // 进度到100%时关闭连接
                if (progressVal >= 100) {
                    sseClient.close();
                    // 可在这里追加任务完成后的逻辑,比如弹出提示、跳转页面等
                }
            }

            // 连接出错时自动关闭
            sseClient.onerror = () => {
                sseClient.close();
            }
        })
    </script>
</body>
</html>

常见问题说明

  • 本地开发测试时如果遇到进度等所有任务跑完才一次性跳到100%,先检查是否开启了Flask的多线程/多进程,默认开发服务器一般不会有该问题;如果后续用Nginx部署,记得关闭对应路径的proxy_buffering配置
  • 如果任务需要用到用户提交的表单/URL参数,和普通Flask路由一样用request对象获取即可,写法没有区别
  • SSE是单向通信通道,仅支持服务端向前端推送数据,完全匹配进度更新的场景,不需要引入额外的第三方服务,学习成本远低于WebSocket

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 13:27:18