在requests.post()中能否同时使用json与files参数?报错排查
关于requests.post()同时使用json和files参数的问题及解决办法
咱们先直接说核心结论:requests.post()不能同时使用json和files参数,这俩参数一起用会导致请求格式混乱,服务器根本没法正确解析,这就是你遇到500错误的原因。
为什么初始代码会失败?
你原来的代码里同时传了json=data和files=files,还手动加了enctype: multipart/form-data头。这里有两个关键问题:
- 当
files参数存在时,requests会自动把请求的Content-Type设为multipart/form-data,并生成必要的boundary分隔符。但json参数会试图把JSON数据直接塞进请求体,这和multipart的格式冲突,服务器拿到的是一团乱码,自然解析不了,所以request.get_json()和request.files.get('image_file1')全是None。 - 手动设置
enctype头完全多余,甚至可能帮倒忙——requests自动生成的头会包含正确的boundary,手动设置的话会丢失这个关键信息,进一步导致解析失败。
为什么修改后的代码会报错?
你把data转成JSON字符串后放到了files字典里,这相当于告诉requests:“把这个JSON字符串当作一个文件来上传”。所以后端request.files['data']拿到的是FileStorage对象(文件类型),而不是纯字符串,json.loads()当然会报错——它只认字符串、字节,不认文件对象。
正确的两种解决办法
方法1:把普通数据作为表单字段和文件一起上传
这是最常规的文件上传+表单数据的做法,requests会自动处理multipart格式:
# 前端代码 import requests data = { 'first_name': self.ids['first_name'].text, 'middle_name': self.ids['middle_name'].text, 'last_name': self.ids['last_name'].text, 'new_comment': self.ids['comment'].text } files = {'image_file1': open(self.file_path1, 'rb')} # 只保留User-Agent头,不需要手动设置enctype headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.90 Safari/537.36'} response = requests.post('http://localhost/users/add', data=data, files=files, headers=headers)
# 后端Flask代码 from flask import request # 表单数据用request.form获取 post_data = { 'first_name': request.form.get('first_name'), 'middle_name': request.form.get('middle_name'), 'last_name': request.form.get('last_name'), 'new_comment': request.form.get('new_comment') } # 文件用request.files获取 image_file1 = request.files.get('image_file1') # 可选:保存文件 if image_file1 and image_file1.filename != '': image_file1.save('/path/to/save/your/image.jpg')
方法2:把JSON数据作为表单的一个字段传递
如果确实需要把部分数据以JSON格式传递,可以把JSON字符串作为表单的一个普通字段,而不是放到files里:
# 前端代码 import json import requests data = { 'first_name': self.ids['first_name'].text, 'middle_name': self.ids['middle_name'].text, 'last_name': self.ids['last_name'].text, 'new_comment': self.ids['comment'].text } # 把data转成JSON字符串,作为表单的一个字段 form_data = {'data_json': json.dumps(data)} files = {'image_file1': open(self.file_path1, 'rb')} headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.90 Safari/537.36'} response = requests.post('http://localhost/users/add', data=form_data, files=files, headers=headers)
# 后端Flask代码 import json from flask import request # 从表单里拿到JSON字符串,再解析成字典 data_json_str = request.form.get('data_json') post_data = json.loads(data_json_str) if data_json_str else {} image_file1 = request.files.get('image_file1')
内容的提问来源于stack exchange,提问作者road_runner
相关产品推荐
相关产品推荐

