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

如何在Flask单路由中维护GET与POST请求间的请求数据状态?

问题出在GET请求不会携带JSON请求体,所以request.get_json()返回None,直接用request_data['user']自然会报NoneType不能下标访问的错误。另外你现在的SQL字符串拼接方式存在严重的SQL注入风险,必须改成参数化查询。

以下是针对性的解决方案,核心是区分GET/POST请求的用户ID获取逻辑,同时修复安全问题:

方案1:用Session存储用户ID(推荐)

既然你之前已经通过POST提交过正确的user_id,把它存在Flask的session里,后续GET请求直接从session读取,不用重复传递:

from flask import session, jsonify

@app.route('/stats', methods=['GET', 'POST'])
def stats():
    # 处理POST请求:接收user_id并存入session
    if request.method == 'POST':
        request_data = request.get_json()
        if not request_data or 'user' not in request_data:
            return jsonify({"error": "请求中缺少用户ID"}), 400
        session['user_id'] = request_data['user']
        user_id = session['user_id']
        stat = get_total_percent_correct(user_id)
        return jsonify({"stat": stat, "user": user_id})
    
    # 处理GET请求:从session获取user_id
    user_id = session.get('user_id')
    if not user_id:
        return jsonify({"error": "用户未验证,请先通过POST提交用户ID"}), 401
    
    # 计算并返回统计数据
    stat = get_total_percent_correct(user_id)
    return jsonify({"stat": stat, "user": user_id})

# 重构统计函数,用参数化查询避免SQL注入
def get_total_percent_correct(user_id):
    # 参数化查询:用%s做占位符,参数单独传入,避免注入风险
    correct = d.db_query('SELECT COUNT(*) FROM cards.responses WHERE guess = answer AND user_id = %s', (user_id,))
    total = d.db_query('SELECT COUNT(*) FROM cards.responses WHERE user_id = %s', (user_id,))
    
    # 处理无数据场景,避免除以0报错
    if total[0][0] == 0:
        return 0.0
    return float(correct[0][0]) / float(total[0][0])

方案2:GET请求通过URL查询参数传递user_id

如果不想用session,也可以让前端在GET请求时把user_id放在URL查询参数里(比如/stats?user=123):

from flask import jsonify

@app.route('/stats', methods=['GET', 'POST'])
def stats():
    user_id = None
    
    if request.method == 'POST':
        request_data = request.get_json()
        if not request_data or 'user' not in request_data:
            return jsonify({"error": "请求中缺少用户ID"}), 400
        user_id = request_data['user']
    else:
        # 从查询参数获取user_id
        user_id = request.args.get('user')
        if not user_id:
            return jsonify({"error": "URL查询参数中缺少用户ID"}), 400
        # 转换为整数(如果你的user_id是数字类型)
        try:
            user_id = int(user_id)
        except ValueError:
            return jsonify({"error": "用户ID格式无效"}), 400
    
    stat = get_total_percent_correct(user_id)
    return jsonify({"stat": stat, "user": user_id})

# 同样修复SQL注入问题
def get_total_percent_correct(user_id):
    correct = d.db_query('SELECT COUNT(*) FROM cards.responses WHERE guess = answer AND user_id = %s', (user_id,))
    total = d.db_query('SELECT COUNT(*) FROM cards.responses WHERE user_id = %s', (user_id,))
    
    if total[0][0] == 0:
        return 0.0
    return float(correct[0][0]) / float(total[0][0])

关键注意事项:

  • 必须处理用户ID缺失的场景,返回明确的错误响应和HTTP状态码,避免程序崩溃。
  • 务必修复SQL注入问题:永远不要用字符串拼接的方式把用户输入直接插入SQL语句,使用参数化查询是行业标准做法。
  • 如果使用session方案,需要在Flask应用初始化时设置SECRET_KEY(比如app.secret_key = 'your_secure_secret_key_here'),否则session无法正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 09:06:17