AJAX重复触发致数据库多条目插入问题求助
解决AJAX多次触发导致重复插入数据库的问题
你的核心问题是事件重复绑定:video.bind("secondchange")是视频每秒触发一次的事件,每次触发都会执行内部代码,反复给表单的submit事件绑定处理函数。随着视频播放,这个绑定会执行几十上百次,点击提交时,所有绑定的函数都会触发,自然就发送了多次AJAX请求,导致数据库插入多条重复记录。
以下是几种可行的解决方案,按优化程度排序:
方案1:绑定事件前先解绑(快速修复)
在给表单绑定submit事件前,先移除已有的同类型事件绑定,确保每次只有一个处理函数生效:
gui_ia_poll.off("submit").on("submit", function(e) { e.preventDefault(); e.stopPropagation(); $.ajax({ url: formURL2, type: 'POST', data: { action: "interactivity_quiz", postId: 56753, videoId: 23457, quizId: 3, questionId: 2, answerId: answer_id }, success: function() { console.log("form submitted"); gui_ia_poll.parents(".gui-ia-slideout").addClass("gui-ia-poll-completed"); gui_ia_item_child.addClass("gui-ia-complete gui-ia-item-active"); // 提交后禁用按钮,防止手动重复点击 $(this).find("input[type='submit']").attr("disabled", true); }, error: function() { console.log("Error with quiz form"); } }); });
方案2:标记提交状态(防止重复请求)
给表单添加一个已提交标记,AJAX请求前检查该标记,避免重复触发:
gui_ia_poll.on("submit", function(e) { e.preventDefault(); e.stopPropagation(); const $form = $(this); // 检查是否已提交,是则直接返回 if ($form.data("submitted")) return; // 标记为已提交 $form.data("submitted", true); $.ajax({ url: formURL2, type: 'POST', data: { action: "interactivity_quiz", postId: 56753, videoId: 23457, quizId: 3, questionId: 2, answerId: answer_id }, success: function() { console.log("form submitted"); gui_ia_poll.parents(".gui-ia-slideout").addClass("gui-ia-poll-completed"); gui_ia_item_child.addClass("gui-ia-complete gui-ia-item-active"); }, error: function() { console.log("Error with quiz form"); // 请求失败时取消标记,允许用户重试 $form.data("submitted", false); } }); });
方案3:重构代码结构(最优解)
既然secondchange每秒都会触发,没必要每次都绑定事件。把事件绑定逻辑移到onReady函数中,只执行一次,用事件委托简化代码:
const formURL2 = `/wp-content/themes/tmm/includes/legacy/externalViewBMlog.php`; _wq.push({ id: "_all", onReady: function(video) { var hashed_ID = video.hashedId(); let poll_start_time; let poll_end_time; var polling_container = $(".poll-container"); var gui_ia_item_child; var gui_ia_item; var question_index = 1; var total_questions; var poll_wistia_parent_id; var answer_id; // ---------- 只执行一次的事件绑定 ---------- // 点击题目展开弹窗 polling_container.on("click", ".gui-ia-item", function() { $(this).next().addClass("gui-ia-slideout-active"); }); // 关闭弹窗 $(document).on("click", ".gui-ia-slideout-close, .gui-ia-poll-results-container button.gui-ia-poll-close", function() { $(".gui-ia-slideout").removeClass("gui-ia-slideout-active"); }); // 选择答案逻辑 polling_container.on("click", ".gui-ia-poll-answer", function() { answer_id = $(this).data("vote"); $(this).closest(".gui-ia-slideout-inner") .find(`.gui-ia-poll-result-container[data-vote="${answer_id}"]`) .addClass("selected") .siblings('[data-vote]').removeClass("selected"); $(this).closest(".gui-ia-poll-answers-container") .find("input[type='submit']").removeAttr("disabled"); }); // 表单提交逻辑 polling_container.on("submit", ".gui-ia-poll", function(e) { e.preventDefault(); e.stopPropagation(); const $form = $(this); if ($form.data("submitted")) return; $form.data("submitted", true); // 动态获取当前题目ID(需根据你的DOM结构调整) const currentQuestionId = $form.closest(".gui-ia-items").find(".gui-ia-item-active").data("question-id"); $.ajax({ url: formURL2, type: 'POST', data: { action: "interactivity_quiz", postId: 56753, videoId: 23457, quizId: 3, questionId: currentQuestionId, answerId: answer_id }, success: function() { console.log("form submitted"); $form.parents(".gui-ia-slideout").addClass("gui-ia-poll-completed"); $form.closest(".gui-ia-items").find(".gui-ia-item-active").addClass("gui-ia-complete"); }, error: function() { console.log("Error with quiz form"); $form.data("submitted", false); } }); }); // ---------- 每秒触发的状态更新逻辑 ---------- video.bind("secondchange", function(seconds) { polling_container.each(function() { poll_wistia_parent_id = $(this).data("wistia-parent-id"); if (hashed_ID === poll_wistia_parent_id) { gui_ia_item_child = $(this).children().find("#gui-ia-item_" + poll_wistia_parent_id + "-" + question_index); gui_ia_item = gui_ia_item_child.parent(); gui_ia_item.show(); total_questions = $(this).children(".gui-ia-items").length; poll_start_time = gui_ia_item_child.data("start-time"); poll_end_time = gui_ia_item_child.data("end-time"); if (seconds >= poll_start_time) { gui_ia_item_child.addClass("gui-ia-item-active"); if (seconds >= poll_end_time) { gui_ia_item_child.removeClass("gui-ia-item-active"); question_index++; } } else if (seconds <= poll_start_time) { gui_ia_item_child.removeClass("gui-ia-item-active"); if (question_index > 1) { question_index--; } } else if (question_index > total_questions) { question_index = total_questions; } } }); }); } });
额外建议:在后端接口也添加重复提交校验(比如根据用户ID+题目ID判断是否已提交),防止前端绕过限制导致的重复插入。
内容的提问来源于stack exchange,提问作者Raj
相关产品推荐
相关产品推荐

