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

如何在FastAPI的Jinja2模板中将Python函数传入JavaScript

解决方案:通过API接口+流式响应实现需求

你遇到的核心问题是Python函数无法直接传递给前端JavaScript执行——两者运行在不同环境,服务器端的Python对象没法直接序列化为可执行的JS代码。正确的做法是把需要执行的逻辑封装成FastAPI接口,前端通过HTTP请求调用它,同时利用FastAPI的流式响应实现进度条更新。

步骤1:后端实现(FastAPI)

把你的Python函数逻辑封装成支持流式返回进度的API接口,用StreamingResponse配合yield实时推送进度数据:

from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
from fastapi.responses import StreamingResponse
import asyncio
import json

app = FastAPI()
templates = Jinja2Templates(directory="templates")

# 模拟带进度的业务任务
async def run_task_with_progress():
    total_steps = 10
    for step in range(total_steps):
        # 替换成你的实际业务逻辑
        await asyncio.sleep(0.5)
        # 生成JSON格式的进度数据,换行分隔便于前端解析
        yield json.dumps({"progress": (step+1)*10}) + "\n"

@app.get("/")
async def read_root(request: Request):
    # 无需传递函数到模板,直接返回页面
    return templates.TemplateResponse("index.html", {"request": request})

@app.get("/execute-task")
async def execute_task():
    # 返回流式响应,支持实时推送进度
    return StreamingResponse(run_task_with_progress(), media_type="text/event-stream")

步骤2:前端模板(index.html)

通过JavaScript的fetch调用后端接口,监听流式响应并更新进度条:

<!DOCTYPE html>
<html>
<head>
    <title>进度条示例</title>
    <style>
        .progress-bar {
            width: 300px;
            height: 20px;
            border: 1px solid #ccc;
            margin-top: 10px;
        }
        .progress-fill {
            height: 100%;
            background-color: #4CAF50;
            width: 0%;
            transition: width 0.3s;
        }
    </style>
</head>
<body>
    <button onclick="startTask()">开始执行任务</button>
    <div class="progress-bar">
        <div class="progress-fill" id="progressFill"></div>
    </div>
    <div id="status"></div>

    <script>
        async function startTask() {
            const progressFill = document.getElementById('progressFill');
            const status = document.getElementById('status');
            
            // 调用后端任务接口
            const response = await fetch('/execute-task');
            const reader = response.body.getReader();
            const decoder = new TextDecoder();

            status.textContent = "任务执行中...";
            
            while (true) {
                const { done, value } = await reader.read();
                if (done) break;
                
                // 解析每一块进度数据并更新DOM
                const data = JSON.parse(decoder.decode(value));
                const progress = data.progress;
                progressFill.style.width = `${progress}%`;
                status.textContent = `进度:${progress}%`;
                
                if (progress === 100) {
                    status.textContent = "任务完成!";
                }
            }
        }
    </script>
</body>
</html>

关键说明

  1. 函数传递的本质问题:Python函数是服务器端内存对象,无法被序列化为前端可执行的代码,必须通过HTTP请求触发执行。
  2. 流式响应的作用:StreamingResponse+yield可以让后端逐步返回进度数据,前端无需等待整个任务完成就能实时更新进度条。
  3. 前端流式数据处理:通过response.body.getReader()逐块读取后端返回的内容,解析后直接更新页面元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 17:24:47