点击按钮发送XMLHttpRequest请求时单次点击触发10次请求的问题排查
问题排查与解决方法
你给出的代码本身逻辑不存在单次点击触发多次请求的问题,可按照以下方向定位根因:
可能的原因
- 事件重复绑定:除了行内
onclick绑定外,你可能在别的JS逻辑中通过addEventListener给该按钮、或其父元素循环绑定了10次点击事件触发fun1,单次点击会触发所有绑定的回调。 - 事件冒泡触发:按钮的上层父/祖父节点也绑定了触发
fun1的点击事件,点击按钮时事件向上冒泡,依次触发了所有上层绑定的同方法。 - 浏览器自动重试:该GET请求没有得到服务端返回的2xx正常响应,浏览器会按照默认策略自动重试失败的请求,视觉上表现为单次点击发送多次请求。
- 行内属性重复编写:按钮标签中不小心重复写了多次
onclick="fun1(this)"属性。
排查步骤
- 打开浏览器开发者工具的「Sources」面板,在
fun1函数第一行加断点,点击按钮观察断点命中次数:- 命中10次:属于事件侧重复触发,按后续步骤排查绑定逻辑
- 仅命中1次:属于请求侧自动重试,排查服务端接口返回
- 事件侧问题排查:选中按钮元素后查看开发者工具右侧「Event Listeners」面板,确认绑定的点击事件数量,删除多余的绑定即可;也可以在
fun1第一行加event.stopImmediatePropagation()临时验证是否是重复绑定问题。 - 请求侧问题排查:打开「Network」面板观察多次请求的状态码,确认是否都是失败重试的请求,修复服务端接口确保能正常返回200响应即可。
防重复提交优化方案
可增加请求锁避免重复触发,修改后的代码如下:
<HTML> <head> <script> // 全局请求锁 let isRequesting = false function fun1(element) { // 已有请求在进行中直接拦截 if(isRequesting) return isRequesting = true var xhttp = new XMLHttpRequest(); xhttp.open("GET", "/pre?"+element.id, true); // 请求完成(无论成功失败)释放锁 xhttp.onloadend = () => { isRequesting = false } xhttp.send(); } </script> </head> <body> <button type="button" onclick="fun1(this)" id="img1">IMAGE</button> </body> </html>
内容的提问来源于stack exchange,提问作者Shubham
相关产品推荐
相关产品推荐

