前端传wav音频到Flask后端触发KeyError: 'audio_data'报错求助
录音上传到Flask后端的KeyError问题修复
核心报错根因
这个BadRequestKeyError: 'audio_data'本质是前后端的请求格式不匹配,加上两处代码硬错,导致后端根本没收到前端传的音频文件字段。
逐点问题定位与修复
1. 后端接收逻辑错误
你当前代码里两处接收音频的写法存在混淆:
- 报错栈显示实际执行的是
request.files['audio_data'],但你贴的源码写的是request.data['audio_data']:request.data是原始请求字节流,不支持按键取表单字段,本来就会报错 - 前端通过
FormData上传文件时,文件内容会被Flask解析到request.files字典里,普通表单值在request.form里,和request.data不是一个通道
正确的后端接收代码写法:
@app.route("/result", methods=['POST','GET']) def result(): if request.method == 'POST': # 先判断字段是否存在,避免直接抛KeyError if 'audio_data' not in request.files: return "未检测到上传的音频文件", 400 audio_file = request.files['audio_data'] # 读取音频字节流传给语音转写模型 audio_bytes = audio_file.read() text = VTT.infer(audio_bytes) print(text) intent = IC.predict(text) print(intent) return render_template("result.html", pred=intent, text=text) else: return redirect(url_for('home'))
2. 前端上传逻辑的硬bug
- 语法错误导致请求根本没发出去:你的
upload函数里用了await调用fetch,但函数本身没有加async修饰,浏览器控制台直接抛语法错误,整个上传流程中断。此时点击按钮实际触发的是<a>标签的默认GET跳转,后端收到GET请求后直接重定向回首页,根本走不到POST分支 - 多余的下载逻辑干扰上传:代码里写的
rec.download()会直接触发浏览器本地下载录音文件,和上传逻辑完全无关,需要删除 - 没有阻止a标签的默认跳转:就算fetch请求发出去了,a标签的默认GET跳转还是会执行,导致请求被中断
- a标签上的
method="POST"是无效属性:<a>标签原生只支持GET请求,根本不识别method属性,属于多余写法
修复后的前端上传代码:
// 加上async标记,支持await语法 async function upload(e) { // 阻止a标签的默认跳转 e.preventDefault(); console.log("Audio being exported.") checkButton.disabled = true; var filename = new Date().toISOString(); rec.exportWAV(async function(blob) { // 校验录音内容是否为空 if (!blob || blob.size === 0) { alert("录音内容为空,请重新录制"); checkButton.disabled = false; return; } var fd = new FormData(); fd.append('audio_data', blob, `${filename}.wav`); try { let r = await fetch('/result', { method: "POST", // 不要手动设置Content-Type,让浏览器自动生成带boundary的multipart格式头 body: fd }); console.log('HTTP response code:', r.status); // 请求成功后跳转结果页 if (r.ok) window.location.href = "/result"; } catch(err) { console.log("上传错误:", err); checkButton.disabled = false; } }); }
同时要修改a标签的onclick调用,把事件对象传进去:
<a id="check" href="/result" class="rounded-lg bg-green-400 hover:bg-green-600 shadow-lg text-xl text-white font-bold my-6 px-16 py-1" onclick="upload(event)">Check intent</a>
后续排查验证步骤
改完代码后可以通过两个点快速验证连通性:
- 打开浏览器开发者工具的Network面板,点击上传时确认:
- 请求方法为POST,不是GET
- 请求体为FormData格式,存在
audio_data字段 - 请求头的Content-Type为
multipart/form-data; boundary=----xxx,不能是不带boundary的纯multipart/form-data
- 后端在路由入口处加一行打印:
print("收到的文件字段:", list(request.files.keys())),确认实际收到的字段名和前端传的是否一致
内容的提问来源于stack exchange,提问作者Stiliyan Ivanov
相关产品推荐
相关产品推荐

