Flask接口GET正常但requests.post提交数据不生效问题
Flask接口POST提交数据不落地问题修复
问题表现
- 基于Flask开发的接口已实现GET、POST请求处理逻辑,当前GET请求可正常返回初始数据,但POST提交新用户账号密码后,服务端未存储对应内容,接口始终返回初始数据集,无法查询到POST上传的新增用户。
原有客户端实现代码
import requests from pprint import pprint base_url = 'http://127.0.0.1:5000' response = requests.get(base_url) data = response.json() #print(data) print("Enter '1' If You Are Existing User") print("Enter '2' If You Want To Make An Account") key=int(input()) if(key==2): print("Enter Your Name For Your Account:") n1=input() print("Enter A Strong Password For Your Account") n2=input() for g in data: if(g['Name'].upper()== n1.upper() and g['Password'].upper()==n2.upper()): print("User Already Exist") break else: payload={'Name':n1,'Password':n2} r=requests.post(base_url,data=payload) pprint(r.json) if(key==1): print("Enter Your Name") name = input() print("Enter Your Password") ent = input() print("\n") for i in data: if(i['Name'].upper()== name.upper() and i['Password'].upper()==ent.upper()): print("Login Succesfull")
问题原因
客户端逻辑问题
- 程序启动时仅拉取一次接口数据存在本地
data变量,后续注册、登录校验全用这份旧数据快照,即使POST请求成功写入了服务端,本地旧数据里也不会有新用户,自然查询不到。 - 用户重名判断逻辑写在遍历存量用户的循环内部,只要遇到第一个不匹配的存量用户就会发起一次POST请求,会导致同一个注册请求被重复发送多次。
- POST传参用了
data=payload,默认发送application/x-www-form-urlencoded格式数据,如果Flask端按JSON格式解析请求体,会直接拿不到提交的账号密码字段。 - 打印响应结果时写的是
pprint(r.json),没有加括号调用方法,实际不会打印接口返回的响应内容,看不到请求报错信息。
服务端常见问题
- 如果用Python全局变量/内存列表存用户数据,Flask默认开启多线程、自动重载时,不同请求可能打到不同的进程实例,内存数据不互通,看起来就像数据没存上;服务重启后内存数据也会全部清空。
- 接口取参方式和客户端传参格式不匹配:客户端发表单就从
request.form取参,发JSON就从request.get_json()取参,格式不匹配会拿到空值,自然没法写入存储。 - 接口逻辑里拿到参数后没有执行数据追加写入的操作,写入逻辑遗漏也会导致数据不落地。
修复参考
修正后的客户端代码
import requests from pprint import pprint base_url = 'http://127.0.0.1:5000' print("Enter '1' If You Are Existing User") print("Enter '2' If You Want To Make An Account") key = int(input()) if key == 2: print("Enter Your Name For Your Account:") n1 = input() print("Enter A Strong Password For Your Account") n2 = input() # 校验前拉取最新的服务端数据 latest_users = requests.get(base_url).json() user_exists = False for user in latest_users: if user['Name'].upper() == n1.upper(): print("User Already Exist") user_exists = True break if not user_exists: payload = {'Name': n1, 'Password': n2} # 和服务端约定用JSON格式传参 resp = requests.post(base_url, json=payload) pprint(resp.json()) if key == 1: print("Enter Your Name") name = input() print("Enter Your Password") ent = input() print("\n") # 登录校验前拉取最新数据 latest_users = requests.get(base_url).json() login_success = False for user in latest_users: if user['Name'].upper() == name.upper() and user['Password'].upper() == ent.upper(): print("Login Succesfull") login_success = True break if not login_success: print("Invalid username or password")
最小可用Flask服务端参考
from flask import Flask, request, jsonify app = Flask(__name__) # *注意:内存存储仅作调试用,生产环境请替换为数据库等持久化存储* user_list = [ {"Name": "demo", "Password": "demo123"} ] @app.route('/', methods=['GET', 'POST']) def user_api(): if request.method == 'GET': return jsonify(user_list) # 解析JSON格式请求体 req_data = request.get_json() username = req_data.get('Name') password = req_data.get('Password') if not username or not password: return jsonify({"code": 400, "msg": "账号或密码不能为空"}), 400 # 写入新用户数据 user_list.append({"Name": username, "Password": password}) return jsonify({"code": 200, "msg": "注册成功"}) if __name__ == '__main__': # 调试阶段关闭多线程,避免多实例内存数据不互通 app.run(debug=True, threaded=False)
内容的提问来源于stack exchange,提问作者Rushil Pajni
相关产品推荐
相关产品推荐

