Python requests.post本地超时求助:Flask同服务器POST请求失败
你遇到的这个挂起问题,核心原因是Flask默认的开发服务器是单线程单进程的!
当你在一个Flask路由函数里发起requests.post请求到同一个服务器的另一个路由时,当前的服务器线程正被这个发起请求的路由占用着,根本腾不出手来处理你刚发的/new_applet请求——相当于自己把自己堵死了,自然会陷入无限等待的挂起状态。
而用curl请求正常的原因很简单:curl是外部发起的独立请求,当服务器处于空闲状态(或者你发起curl时,那个发起请求的路由没在运行),服务器能立刻处理这个请求,所以不会有问题。
1. 开启Flask服务器的多线程模式
最简单的解决方法就是启动Flask时显式开启多线程,这样服务器就能同时处理多个请求了:
if __name__ == '__main__': app.run(threaded=True) # 开启多线程
如果你的项目用了debug模式,Werkzeug(Flask底层的服务器)默认会开启多线程,但显式设置threaded=True更稳妥,能避免版本差异导致的问题。
2. 直接调用视图函数(更优雅的做法)
如果业务逻辑允许,完全没必要通过HTTP请求调用自身路由——你可以直接调用/new_applet对应的视图函数,跳过HTTP请求的开销,也从根源上避免线程阻塞:
比如假设/new_applet对应的视图函数是handle_new_applet,那你可以在发起请求的路由里这样写:
# 代替requests.post的HTTP调用,直接执行视图函数逻辑 result = handle_new_applet(action="add", plugin=plugin, version=version, component=component)
3. 额外检查:请求格式匹配(非挂起原因,但可优化)
虽然这不是你当前挂起的根源,但可以顺便确认:你的curl命令用--form发送的是multipart/form-data格式数据,而requests.post(url, data=data)默认发送的是application/x-www-form-urlencoded格式。如果你的/new_applet路由依赖特定的表单格式(比如用到request.files),可以把requests请求改成用files参数模拟表单上传:
# 模拟curl的--form格式发送请求 resp = requests.post(url, files=data)
内容的提问来源于stack exchange,提问作者XDGFX

