如何通过Python Requests向Flask应用上传文件并附带数据解决400报错
错误原因
当requests请求同时携带files和data参数时,会自动使用multipart/form-data格式编码请求,这种格式下不存在JSON格式的请求体,Flask调用request.get_json()时无法解析到有效JSON数据,因此抛出异常返回400。
另外你最初的客户端代码也存在问题:定义了data参数但没有传入requests.post方法中,即使服务端逻辑正确也拿不到对应参数。
解决方案
方案1:从表单字段读取普通参数(改动最小,适合简单参数场景)
客户端修改
把data参数传入请求方法:
url = "https://some-random-url.com/" files = {'file': open("shared/assets/12332.png", 'rb')} data = {"lobby_id": "lobby_id"} # 传入data参数 r = requests.post(url=url, files=files, data=data)
服务端修改
从request.form中读取普通参数,不要调用get_json:
@app.route('/', methods=['GET', 'POST']) def upload_file(): if request.method == 'POST': temp_image = request.files['file'] # 从表单字段取值 lobby_id = request.form.get('lobby_id') filename = secure_filename(temp_image.filename) temp_image.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) return 'Success'
方案2:序列化JSON传递(适合复杂嵌套参数场景)
如果需要传递结构复杂的嵌套数据,可以将JSON序列化为字符串作为表单字段传递,服务端再反序列化读取:
客户端代码
import json url = "https://some-random-url.com/" files = {'file': open("shared/assets/12332.png", 'rb')} # 构造复杂参数后序列化为JSON字符串 complex_data = {"lobby_id": "lobby_id", "extra": {"user": "xxx", "time": 12345}} form_data = {"json_payload": json.dumps(complex_data)} r = requests.post(url=url, files=files, data=form_data)
服务端代码
import json @app.route('/', methods=['GET', 'POST']) def upload_file(): if request.method == 'POST': temp_image = request.files['file'] # 读取字符串后反序列化为字典 json_payload = json.loads(request.form.get('json_payload')) lobby_id = json_payload.get('lobby_id') filename = secure_filename(temp_image.filename) temp_image.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) return 'Success'
内容的提问来源于stack exchange,提问作者Merlin DarkWiz
相关产品推荐
相关产品推荐

