从HTML向Python Flask应用发送POST请求并接收流式数据报错求助
问题解决:Flask流式响应前端逐词展示异常
问题现象
页面发送POST请求到/python_app/返回200 OK,但后续触发的GET请求返回405 Method Not Allowed;修改Flask路由后又出现404错误,无法实现类似ChatGPT的逐词流式输出效果。
问题根源
- 路由路径不匹配:原Flask路由绑定的是根路径
/,但前端请求的是/python_app/,导致路由无法匹配。 - 前端逻辑错误:使用普通AJAX POST后再用
EventSource发起GET请求,这是错误的——我们需要的是POST请求直接返回流式响应,不需要额外的GET请求;同时jQuery的AJAX默认不支持流式接收响应,会等待全部数据加载完成才触发回调。 - 全局变量风险:修改后的代码用全局
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
相关产品推荐
相关产品推荐

