点击按钮触发多次AJAX请求 求技术排查协助
排查点击按钮触发多次AJAX请求的问题
点击#saveaudios按钮时,AJAX请求被多次触发,以下是相关代码及排查方向:
相关代码
Blade模板中的按钮部分
<div class="form-group"> @if(!empty($textLesson)) @php $text_id=$textLesson->id; $webinar_id=$webinar->id; $lessonAudio = App\Models\AudioAttachment::where('text_lesson_id',$text_id)->get(); @endphp <div id="btnDiv"> <x-panel.attach-audio-component :textid="$text_id" :webinarid="$webinar_id" :textLesson="$textLesson" :userLanguages="$userLanguages" /> </div> @if(!empty($lessonAudio) and !$lessonAudio->isEmpty()) <div id="audioListings"> </div>
AJAX脚本部分
$(document).ready(function () { $('body').on('click', '#addAudio', function (e) { const $this = $(this); $textid = document.getElementById("addAudio").getAttribute("data-text-id"); $webinarid = $this.attr('data-webinar-id'); e.preventDefault(); let add_audio_modal = '<form id="addAudioFiles" method="post" action="/panel/text-lesson/saveaudio" enctype= "multipart/form-data">'; add_audio_modal += '@csrf'; add_audio_modal += $('#audioFilesModal').html(); add_audio_modal += '</div>'; Swal.fire({ html: add_audio_modal, showCancelButton: false, showConfirmButton: false, customClass: { content: 'p-0 text-left', }, width: '48rem', }); }); $('body').on('click', '#saveaudios', function (e) { e.preventDefault(); const $this = $(this); let form = $('#addAudioFiles'); let formData = new FormData(form[0]); formData.append('webinar_id', $webinarid); formData.append('text_id', $textid); let action = form.attr('action'); $this.addClass('loadingbar gray').prop('disabled', true); form.find('input').removeClass('is-invalid'); form.find('textarea').removeClass('is-invalid'); $.ajax({ url: action, type: 'POST', data: formData, processData: false, contentType: false, success: function (result) { if (result && result.code === 200) { // 处理结果 } }, error: function (err) { // 错误处理 } }); }); });
可能的原因及解决方案
1. 事件重复绑定
使用$('body').on('click', '#saveaudios', ...)的事件委托方式时,若脚本被多次执行(比如页面局部刷新、组件重复渲染),会重复绑定点击事件,每次绑定都会在点击时触发一次请求。
解决方法:给事件添加命名空间,绑定前先移除同名事件:
// 替换原有的#saveaudios事件绑定代码 $('body').off('click.audioSave').on('click.audioSave', '#saveaudios', function (e) { // 原事件处理逻辑 });
2. 弹窗DOM未清理,旧事件残留
每次打开Swal弹窗时会生成新的#saveaudios按钮,但旧弹窗的DOM可能未被完全销毁,导致旧的事件监听仍然存在,点击时多个监听同时触发。
解决方法:利用Swal的willClose回调清理DOM和事件:
Swal.fire({ html: add_audio_modal, showCancelButton: false, showConfirmButton: false, customClass: { content: 'p-0 text-left', }, width: '48rem', willClose: () => { $('#addAudioFiles').remove(); // 移除弹窗内的表单 $('body').off('click.audioSave'); // 移除事件监听 } });
3. 全局变量引发的潜在问题
$webinarid和$textid是全局变量,多次打开弹窗会覆盖变量值,虽不是请求多次的直接原因,但可能导致请求参数错误,同时若脚本重复执行,全局变量的存在也可能间接引发其他问题。
解决方法:将参数存入表单隐藏域,避免全局变量:
// 生成弹窗表单时添加隐藏域 let add_audio_modal = '<form id="addAudioFiles" method="post" action="/panel/text-lesson/saveaudio" enctype= "multipart/form-data">'; add_audio_modal += '@csrf'; // 添加隐藏域存储参数 add_audio_modal += `<input type="hidden" name="webinar_id" value="${$webinarid}">`; add_audio_modal += `<input type="hidden" name="text_id" value="${$textid}">`; add_audio_modal += $('#audioFilesModal').html(); add_audio_modal += '</form>'; // 修正原代码中错误的</div>为</form>
然后在AJAX中无需手动append参数,直接从FormData获取:
let formData = new FormData(form[0]); // 移除这两行:formData.append('webinar_id', $webinarid); formData.append('text_id', $textid);
4. HTML结构错误
原代码中生成表单时最后是'</div>',但开头是<form>,标签不匹配会导致DOM结构异常,可能间接引发事件绑定问题,需修正为'</form>'。
内容的提问来源于stack exchange,提问作者Maryam Aftab
相关产品推荐
相关产品推荐

