You need to enable JavaScript to run this app. 前端传wav音频到Flask后端触发KeyError: 'audio_data'报错求助
优惠活动
大模型
产品
解决方案
定价
更多

前端传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>

后续排查验证步骤

改完代码后可以通过两个点快速验证连通性:

  1. 打开浏览器开发者工具的Network面板,点击上传时确认:
    • 请求方法为POST,不是GET
    • 请求体为FormData格式,存在audio_data字段
    • 请求头的Content-Type为multipart/form-data; boundary=----xxx,不能是不带boundary的纯multipart/form-data
  2. 后端在路由入口处加一行打印:print("收到的文件字段:", list(request.files.keys())),确认实际收到的字段名和前端传的是否一致

内容的提问来源于stack exchange,提问作者Stiliyan Ivanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.10 08:54:04