You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Fetch发送POST请求后页面重复刷新问题排查

页面发送音频POST请求后自动刷新的问题排查与解决

问题场景

使用JavaScript录制语音片段后,通过Fetch发送POST请求到本地Flask服务器处理,但在片段发送时及处理完成后,页面都会自动刷新,已尝试e.preventDefault()但未解决。

录制音频函数

recordButton.onmousedown = e => {
  
  console.log('Recording...');
  audioChunks = [];
  navigator.mediaDevices.getUserMedia({ audio: true })
      .then(stream => {
          rec = new MediaRecorder(stream);
          rec.ondataavailable = e => {
              audioChunks.push(e.data);
              if (rec.state == "inactive") {
                  let blob = new Blob(audioChunks, { type: 'audio/mpeg-3' });
                  recordedAudio.src = URL.createObjectURL(blob);
                  inputAudio = recordedAudio.src
                  recordedAudio.controls = true;
                  sendData(blob);
              }
          }
          rec.start();
      });
};

发送数据函数

async function sendData(data) {

    const formData = new FormData();
    
    formData.append('audio', data);
    console.log("audio appended")
    fetch('http://127.0.0.1:5000/upload-audio', {
        method: 'POST',
        body: formData
    })
    .then(response => response.json())
    console.log("audio downloaded")
    .then(data => {
        console.log(data.response);
        // Download audio response file
        
        console.log("audio downloaded")
    })
    .catch(error => {
        console.error('Error:', error);
    });
    
}

问题根源

页面刷新的核心原因是按钮的默认表单提交行为,而非Fetch请求本身:

  1. 如果recordButton是<button>标签(未指定type="button"),或者是<input type="submit">,且位于<form>标签内,点击时会触发表单的默认提交动作,导致页面刷新。
  2. 仅在mousedown事件中调用e.preventDefault()可能无法完全阻止后续的click事件默认行为,因为mousedown和click是两个独立的事件。

解决方案

1. 修改按钮HTML类型

确保按钮不会触发表单提交:

<!-- 明确指定按钮类型为button,而非默认的submit -->
<button type="button" id="recordButton">开始录制</button>

2. 彻底阻止按钮事件的默认行为

在mousedown和click事件中都添加阻止默认行为和事件冒泡的代码:

recordButton.onmousedown = e => {
  // 阻止默认行为和事件冒泡
  e.preventDefault();
  e.stopPropagation();
  
  console.log('Recording...');
  audioChunks = [];
  navigator.mediaDevices.getUserMedia({ audio: true })
      .then(stream => {
          rec = new MediaRecorder(stream);
          rec.ondataavailable = e => {
              audioChunks.push(e.data);
              if (rec.state == "inactive") {
                  let blob = new Blob(audioChunks, { type: 'audio/mpeg-3' });
                  recordedAudio.src = URL.createObjectURL(blob);
                  inputAudio = recordedAudio.src
                  recordedAudio.controls = true;
                  sendData(blob);
              }
          }
          rec.start();
      });
};

// 额外绑定click事件,彻底阻止默认行为
recordButton.onclick = e => {
  e.preventDefault();
  e.stopPropagation();
};

3. 修正sendData函数的逻辑问题

原函数中console.log("audio downloaded")写在then链之外,会导致日志提前输出,修正后确保逻辑顺序正确:

async function sendData(data) {
    const formData = new FormData();
    formData.append('audio', data);
    console.log("audio appended");
    
    fetch('http://127.0.0.1:5000/upload-audio', {
        method: 'POST',
        body: formData
    })
    .then(response => response.json())
    .then(data => {
        console.log(data.response);
        console.log("audio downloaded");
    })
    .catch(error => {
        console.error('Error:', error);
    });
}

验证

完成以上修改后,再次测试录制和发送流程,页面将不会再自动刷新,可正常进行调试操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 03:17:05