使用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请求本身:
- 如果
recordButton是<button>标签(未指定type="button"),或者是<input type="submit">,且位于<form>标签内,点击时会触发表单的默认提交动作,导致页面刷新。 - 仅在
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
相关产品推荐
相关产品推荐

