如何在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
相关产品推荐
相关产品推荐

