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

从HTML向Python Flask应用发送POST请求并接收流式数据报错求助

问题解决:Flask流式响应前端逐词展示异常

问题现象

页面发送POST请求到/python_app/返回200 OK,但后续触发的GET请求返回405 Method Not Allowed;修改Flask路由后又出现404错误,无法实现类似ChatGPT的逐词流式输出效果。

问题根源

  1. 路由路径不匹配:原Flask路由绑定的是根路径/,但前端请求的是/python_app/,导致路由无法匹配。
  2. 前端逻辑错误:使用普通AJAX POST后再用EventSource发起GET请求,这是错误的——我们需要的是POST请求直接返回流式响应,不需要额外的GET请求;同时jQuery的AJAX默认不支持流式接收响应,会等待全部数据加载完成才触发回调。
  3. 全局变量风险:修改后的代码用全局words存储消息,会导致多用户请求时数据混乱,且返回的是历史所有内容而非当前请求的消息。

修正方案

修正后的Flask代码(app.py)

from flask import Flask, request, Response
import time

app = Flask(__name__)

@app.route("/python_app/", methods=["POST"])
def handle_message():
    message = request.form.get("message", "")
    words = message.split()
    
    def event_stream():
        for word in words:
            time.sleep(1)
            # Server-Sent Events格式要求:data字段后必须跟两个换行
            yield f"data: {word}\n\n"
    
    return Response(event_stream(), mimetype="text/event-stream")

if __name__ == "__main__":
    # 开启线程支持多流式请求,生产环境请关闭debug
    app.run(debug=True, threaded=True)

修正后的前端代码(index.html)

<!DOCTYPE html>
<html>
<head>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
  <input type="text" id="messageInput" />
  <button id="sendButton">Send</button>
  
  <div id="output"></div>

  <script>
    $("#sendButton").click(function() {
      var message = $("#messageInput").val();
      var outputDiv = $("#output");
      outputDiv.empty(); // 清空上一次的输出内容

      // 使用Fetch API处理POST流式响应
      fetch("/python_app/", {
        method: "POST",
        body: new URLSearchParams({ message: message }),
        headers: {
          "Content-Type": "application/x-www-form-urlencoded"
        }
      }).then(response => {
        const reader = response.body.getReader();
        const decoder = new TextDecoder();
        
        function readStream() {
          reader.read().then(({ done, value }) => {
            if (done) return;
            // 解码流式片段并处理Server-Sent Events格式
            const chunk = decoder.decode(value);
            const messages = chunk.split("\n\n").filter(msg => msg.startsWith("data: "));
            messages.forEach(msg => {
              const word = msg.replace("data: ", "").trim();
              if (word) {
                outputDiv.append(word + "<br>");
              }
            });
            readStream();
          });
        }
        
        readStream();
      }).catch(err => {
        console.error("请求出错:", err);
      });
    });
  </script>
</body>
</html>

关键说明

  • Flask端:确保路由路径与前端请求一致,返回text/event-stream类型响应,每个流式片段严格遵循Server-Sent Events格式。
  • 前端:用Fetch API替代jQuery AJAX,Fetch支持读取ReadableStream,可以逐段接收数据并实时更新页面。
  • 部署注意:Flask默认单线程,需开启threaded=True才能同时处理多个流式请求;生产环境建议使用Gunicorn等支持异步的服务器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:47:45