为何每次后续的Ajax请求次数会随调用次数倍增?
为什么你的Ajax请求会倍增?问题解析与修复方案
嘿,我一眼就看穿问题所在了——你的事件绑定逻辑出了个小疏漏,导致每次点击按钮都会给表单的submit事件多绑一次处理器,请求次数自然就翻倍了!
问题根源:重复绑定事件处理器
看你这段代码:
$('#trigger').click(function() { $('form').submit(function(e) { // 这里是submit的处理逻辑 }); });
每次点击#trigger按钮时,都会执行$('form').submit(...)——这不是替换原有事件处理器,而是新增一个。第一次点击后,表单有1个submit处理器;第二次点击,又加1个变成2个;第三次点击再加1个变成3个……所以每次提交表单时,所有绑定的处理器都会被触发,对应的Ajax请求就会发送N次(N等于你点击按钮的次数),看起来就是请求次数倍增了。
修复方案:调整事件绑定逻辑
最优的解决方式是把表单的submit事件绑定移到#trigger的点击回调外面,因为表单的提交逻辑只需要绑定一次,不需要每次点击按钮都重复绑定。
修改后的完整代码如下:
$(document).ready(function() { // 把变量放在ready内部,避免全局污染 var $loading = $('#load').hide(); var $listen = $('#trigger'); var $play = $('#play-btn').hide(); // 监听输入框按键,启用"GET VOICE"按钮 $('#dataText').keyup(e => { $('#trigger').removeAttr('disabled'); $listen.show(); $play.hide(); }); // 直接绑定表单submit事件,只执行一次 $('form').submit(function(e) { e.preventDefault(); // 阻止表单默认提交行为 var textdata = $('#dataText').val(); var postData = textdata; $.ajax({ async: true, crossDomain: true, url: "https://voicerss-text-to-speech.p.rapidapi.com/?", method: "POST", headers: { 'content-type': "application/x-www-form-urlencoded", 'X-RapidAPI-Key': "", // 记得填入你的API Key 'X-RapidAPI-Host': "voicerss-text-to-speech.p.rapidapi.com" }, data: { src: postData, hl: "en-us", r: "0", c: "mp3", f: "8khz_8bit_mono", b64: true }, }).done(function (response) { $('#player').html(`<audio id="myAudio"><source src=${response}></audio>`); }); // Ajax状态切换 $(document) .ajaxStart(function () { $listen.hide(); $loading.show(); }) .ajaxStop(function () { $loading.hide(); $listen.hide(); $play.show(); }); console.log(postData); }); // 点击"GET VOICE"按钮时,手动触发表单提交 $('#trigger').click(function() { $('form').submit(); }); }); function playAudio() { let myAudio = document.getElementById("myAudio"); myAudio.play(); }
关键修改点说明
- 事件绑定位置调整:把表单
submit事件的绑定移到$(document).ready()顶层,只执行一次,避免重复绑定处理器。 - 按钮点击逻辑简化:
#trigger的点击回调不再绑定事件,而是直接手动触发表单的submit事件,确保每次点击只触发一次提交。 - 变量作用域优化:把
$loading、$listen、$play移到ready函数内部,避免全局变量污染,代码更规范。
备选方案(快速临时修复)
如果不想大改结构,也可以在绑定submit事件前先解绑原有绑定,确保每次只绑定一个处理器:
$('#trigger').click(function() { // 先移除所有submit绑定,再添加新的 $('form').off('submit').on('submit', function(e) { // 原有的submit处理逻辑 }); });
不过这种方式不如第一种优雅,因为没必要每次都解绑再绑定,优先推荐第一种方案。
核心逻辑总结
这个问题的本质是事件处理器的重复累积——在事件回调内部绑定其他事件,会导致每次触发外层事件时,都给内层事件新增一个处理器。以后写代码时要注意:除非有特殊需求,否则不要在事件回调中嵌套绑定其他事件,避免出现这类重复触发的问题。
内容的提问来源于stack exchange,提问作者Tmk Plzv
相关产品推荐
相关产品推荐

