
当表单内存在多个提交类按钮(如 type="submit")时,点击任一按钮均会触发表单提交事件,导致多个 ajax 请求被意外发起,进而使不同事件的 success 回调相互干扰;解决关键在于明确区分“表单提交”与“普通点击”行为,并正确阻止默认动作。
当表单内存在多个提交类按钮(如 type="submit")时,点击任一按钮均会触发表单提交事件,导致多个 ajax 请求被意外发起,进而使不同事件的 success 回调相互干扰;解决关键在于明确区分“表单提交”与“普通点击”行为,并正确阻止默认动作。
问题根源在于:#test-template 按钮虽被绑定 click 事件,但它本身是 <button type="submit">(或未显式声明 type 时浏览器默认为 submit),因此点击它不仅触发 click,还会自动触发表单的 submit 事件——这正是两个 success 回调被重复执行的根本原因:两个独立的 AJAX 请求被并发发出,而非“一个请求触发两个回调”。
✅ 正确解决方案(二选一)
方案一:在 click 处理器中显式阻止默认行为(推荐)
只需为 #test-template 的 click 事件添加 event.preventDefault(),即可中断其默认的表单提交流程,确保仅执行你定义的 AJAX 请求:
$(document).on("click", "#test-template", function(event) {
event.preventDefault(); // ? 关键:阻止表单提交
var formData = $("#template_informations").serialize();
$.ajax({
type: "POST",
url: "/marketing/gpnews/template",
data: formData,
success: function(data) {
var test_field = $(".test-field");
var textoHTML = decodeEntities(data.html);
const div = document.createElement('div');
const parser = new DOMParser();
const parsedHTML = parser.parseFromString(textoHTML, 'text/html');
div.appendChild(parsedHTML.documentElement);
test_field.html(div);
}
});
});⚠️ 注意:e.preventDefault() 必须放在 $.ajax() 调用之前,且不能遗漏。
方案二:将测试按钮改为非提交类型(语义更清晰)
若 #test-template 本意并非提交表单,而仅用于预览/测试,则应从 HTML 层面修正语义:
<!-- ❌ 错误:submit 按钮会触发表单提交 --> <button id="test-template" type="submit">测试模板</button> <!-- ✅ 正确:普通按钮,无默认提交行为 --> <button id="test-template" type="button">测试模板</button>
此时无需 preventDefault(),click 事件将纯净执行,彻底规避冲突。
? 验证与调试建议
- 使用浏览器开发者工具的 Network 标签页 观察实际发出的请求:修复后,点击 #test-template 应仅出现 1 个 /marketing/gpnews/template 请求,而非 2 个。
- 检查按钮的 type 属性是否被其他脚本动态修改(如某些 UI 框架可能重写 type),必要时在事件处理器开头打印 this.type 进行确认。
? 总结
表单内混用 submit 按钮与自定义 click 行为是常见陷阱。核心原则是:让每个交互有唯一、明确的语义归属——提交表单用 submit + submit 事件;触发辅助操作(如预览、校验、AJAX 测试)则用 type="button" + click 事件。二者不可混淆,否则必然引发事件冒泡与默认行为干扰。


















