@app.route('/auth/audio/save', methods=['POST'])
def save_audio():
# files = request.files
resp_dict = {'message': "success"}
file = request.files.get("file")
if file.filename == "":
resp_dict['message'] = "[No file] file.filename == ''"
return jsonify(resp_dict), 400
# data = request.get_json()
data = request.form
logger.info(f"data: {data}")
check_required_params(data, ['user_id'])
user_id = data["user_id"]
audio_dir = os.path.join(app_dir, 'db_files/audio')
save_path = os.path.join(audio_dir, f'{user_id}.bin')
file.save(save_path)
return jsonify(resp_dict), 200
我有一个 Flask 视图函数,它处理 POST 请求,该请求发送包装在请求正文中的文件和数据。
发送请求代码如下所示:
def test_send_audio():
cur_dir = os.path.dirname(os.path.abspath(__file__))
audiopath = os.path.join(cur_dir, "test.wav")
files = {'file': open(audiopath, 'rb')}
data = {"user_id": 2}
# headers = {
# "Content-Type": "multipart/form-data",
# }
# NOTE: Not sure why handlers can't get files when I add headers
response = requests.post(
save_audio_url,
# headers=headers,
files=files,
data=data,
)
request.form
存储表单数据。 request.get_json()
获取请求正文中的 JSON 数据。这两种类型的数据通过其媒体类型来区分。表单数据将为 multipart/form-data
、application/x-www-form-urlencoded
或 application/x-url-encoded
。 JSON 数据将是 application/json
。这里的区别在于 multipart/form-data
可以处理文件上传,这就是您在这里所做的,而 application/json
则不能。当您发送不涉及文件的结构化数据时,JSON 数据是更好的选择。
顾名思义,
multipart
类型是具有多个部分的数据。不同的部分应该用“边界”分隔,“边界”是分隔这些不同数据块的任意字符串。更好的解释是here。在您的代码中,requests
库将自动生成边界并使用该边界填充请求正文中的数据。因此,您不应在标头中手动指定内容类型。您可以尝试打印 request.headers
和 request.get_data()
来查看这一点。
您正在尝试接收文件并使用
user_id
作为文件名保存它。我假设 user_id
是发送此请求的用户的 ID(如果是这种情况请告诉我)。我们通常不会在请求正文中存储或发送会话信息(在本例中为user_id
),因为这是一种很差的安全实践。相反,我们将会话信息编码在令牌(通常是 JWT 令牌)中,并将其放入请求标头中。
希望有帮助。