Ajax提交响应次数逐次递增问题排查求助
问题根源与修复方案
核心原因
你遇到的响应次数逐次递增问题,本质是全局的XMLHttpRequestObject被重复绑定了事件监听器。每次点击提交按钮调用sendAjaxFormData时,都会给同一个全局XHR对象添加新的load和error回调函数,这些回调不会自动清除。第一次提交时只有1个回调触发,第二次就有2个,以此类推,直到刷新页面重置全局对象。
修复方案
推荐直接每次请求创建新的XHR实例,彻底避免复用对象导致的重复绑定问题,同时也不需要维护全局变量,代码更健壮。
修改后的代码
JS代码
function sendAjaxFormData(url, frmName) { // 每次请求创建新的XHR实例 let XMLHttpRequestObject = false; if (window.XMLHttpRequest) { XMLHttpRequestObject = new XMLHttpRequest(); } else if (window.ActiveXObject) { XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP"); } const jsonString = formToJson(frmName); console.log(jsonString); // 绑定单次请求的事件回调 XMLHttpRequestObject.addEventListener('load', (event) => { alert('Yeah! Data sent and response loaded.'); }); XMLHttpRequestObject.addEventListener('error', (event) => { alert('Oops! Something went wrong.'); }); XMLHttpRequestObject.open('POST', url, true); XMLHttpRequestObject.setRequestHeader("Content-Type", "application/json"); XMLHttpRequestObject.send(jsonString); } function formToJson(frmName) { var form = document.getElementById(frmName); var frmDict = {}; for(let field of form.elements) { frmDict[field.name] = field.value; } return JSON.stringify(frmDict); }
HTML代码(无需修改)
<form name="frmTest" id="frmTest" method="post" class="basic" action=""> <input type="text" name="field1" id="field1" value="" style="width:200px;" /><br /> <input type="text" name="field2" id="field2" value="" style="width:200px;" /><br /> <input type="text" name="field3" id="field3" value="" style="width:200px;" /><br /> <input type="button" name="btnTest" value="Test" onclick="sendAjaxFormData('URL_GOES_HERE', 'frmTest');" /> </form>
其他可选修复思路
如果一定要复用XHR对象,可以在每次添加监听器前移除旧的回调,或者使用addEventListener的once: true选项(现代浏览器支持),确保回调只执行一次:
// 使用once选项,回调触发后自动移除 XMLHttpRequestObject.addEventListener('load', (event) => { alert('Yeah! Data sent and response loaded.'); }, { once: true });
内容的提问来源于stack exchange,提问作者TorontoJim
相关产品推荐
相关产品推荐

