为何Ajax请求被触发两次?附Django前后端相关代码
Ajax请求触发两次的原因及解决办法
核心原因分析
事件重复绑定
如果你的JS脚本被重复引入(比如模板中多次加载同一个JS文件),$('body').on('click','td', ...)会被绑定多次,导致每次点击td都会触发多轮Ajax请求。Bootstrap Tooltip的额外事件干扰
你的td标签添加了data-toggle="tooltip"属性,Bootstrap Tooltip组件在初始化或交互过程中,可能会触发额外的点击事件(即使默认触发方式是hover,某些场景下也会因元素交互产生二次事件)。事件委托范围过大+无过滤逻辑
绑定在body上的td点击事件范围太广,且没有判断当前点击的td是否包含目标id,导致无id的td也会触发请求,同时可能在事件冒泡过程中被重复捕获。
针对性解决办法
1. 避免事件重复绑定
给事件添加命名空间,或者先解绑再绑定,确保事件只绑定一次:
// 先解绑同名命名空间的事件,再绑定 $('body').off('click.tdToggle').on('click.tdToggle','td', function(e) { e.stopPropagation(); var _id = $(this).attr('id'); // 只处理带有id的td,过滤无效点击 if (!_id) return; $.ajax({ type: 'POST', url: "{% url 'monitoring:deactivate_dcf' %}", data: { "id" : _id }, dataType: 'json', // 后端返回Json,直接设为json无需手动parse success: function (response) { // 同步更新页面显示,避免状态不一致 $(this).text(response.deactivated); }, error: function(xhr) { console.log(xhr.responseText); } }); });
2. 消除Tooltip的事件干扰
显式指定Tooltip的触发方式为hover,避免点击触发额外事件:
<td data-toggle="tooltip" data-placement="top" title="" data-trigger="hover">{{ dcf.ide }}</td> <td data-toggle="tooltip" data-placement="top" title="" data-trigger="hover" id="{{ dcf.ide }}">{{ dcf.deativated }}</td>
3. 优化后端逻辑(减少冗余查询+避免竞态)
当前后端多次查询数据库,且未处理并发请求问题,可优化为:
@login_required @csrf_exempt def deactivate_dcf(request): if request.is_ajax() and request.method == "POST": datacorrection_id = request.POST.get("id") try: # 加行锁避免并发请求导致状态混乱 dcf = DataCorrection.objects.select_for_update().get(ide=datacorrection_id) dcf.deativated = not dcf.deativated dcf.save() # 返回更新后的状态,方便前端同步页面 return JsonResponse({"response": "success", "deactivated": dcf.deativated}, status=200) except DataCorrection.DoesNotExist: return JsonResponse({"response": "failed","exist":"datacorrection not exist"}, status=404) return JsonResponse({"response":"not_ajax"}, status=200)
内容的提问来源于stack exchange,提问作者Mereva
相关产品推荐
相关产品推荐

