You need to enable JavaScript to run this app. Python Flask 跳转index路由报GET请求异常如何解决
优惠活动
大模型
产品
解决方案
定价
更多

Python Flask 跳转index路由报GET请求异常如何解决

报错根因

这个问题和redirect(url_for("index"))的跳转逻辑没有直接关系,本质是全局复用的MySQL连接状态异常触发的。
mysql-connector-python的连接对象有个硬规则:同一时刻连接上只能存在一个未完全消费完结果集的游标。你现在的执行流程刚好踩中了这个坑:

  1. 登录路由处理POST请求时,执行了账号校验的数据库查询
  2. 查询完成后没有把游标里的结果全部读取,也没有显式关闭游标,结果集一直占着连接
  3. 登录成功后触发重定向,浏览器发出全新的GET请求到index路由
  4. index路由直接复用同一个全局的mydb连接申请新游标
  5. 连接检测到之前还有没读完的残留结果,直接抛出Unread result found中断请求
可直接落地的修复方案
  • 先把游标的使用规范改对,从根上消除残留未读结果
    所有执行过查询的游标,要么显式调用fetchall()/fetchone()把结果取完,要么操作完成后立刻调用cursor.close()关闭。比如登录路由里的查询操作正确写法:
    cursor = mydb.cursor()
    cursor.execute("SELECT id, username FROM users WHERE username = %s AND password = %s", (username, password))
    login_user = cursor.fetchone()
    cursor.close()  # 操作完马上关,不要拖到请求结束
    if login_user:
        session["user_id"] = login_user[0]
        return redirect(url_for("index"))
    
  • 别再全局复用单个MySQL连接对象
    Flask是多线程并发处理请求的,全局单例的数据库连接本身就不是线程安全的,很容易出现不同请求共用同一个连接、互相干扰连接状态的问题。最小改动的方案是:把数据库连接的初始化放到请求上下文里,每次请求单独建连接,请求结束自动销毁。想更省改动的话,可以在Flask的teardown_appcontext钩子中,每次请求结束就主动关闭现有数据库连接,下次请求再重新初始化。
  • 临时兼容方案:给连接加缓冲配置
    如果暂时不想大改连接逻辑,可以在初始化mydb的时候加上buffered=True参数,这个配置会让连接自动把查询结果存在本地缓冲区,就算你没主动读完结果,也不会触发未读结果的校验。但这只是绕开了报错,并没有解决全局连接线程不安全的核心问题,不适合长期使用。
关于GET请求适配的判断

你之前推测的“需要对GET请求做相关适配”方向有点偏。登录路由是单次POST请求,处理完的时候之前的游标还占着连接状态没释放;重定向触发的是浏览器发的全新GET请求,这个新请求拿到的还是那个带残留未读结果的旧连接,自然一申请新游标就报错,根本不需要给GET请求加特殊逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 18:36:08