
当表单内存在多个按钮(如一个用于正式提交、另一个用于预览测试)时,若均使用 ,点击任一按钮都会触发表单 submit 事件,导致多个 AJAX 请求并发执行,进而引发 success 回调相互干扰。核心解法是明确区分行为意图:仅主提交按钮应触发表单提交逻辑,测试按钮必须阻止默认提交行为或改用非提交类型按钮。
当表单内存在多个按钮(如一个用于正式提交、另一个用于预览测试)时,若均使用 `
问题本质并非“同一个请求触发两个 success 函数”,而是两个独立的 AJAX 请求被意外同时发起——因为 #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,
dataType: "json",
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);
}
});
});⚠️ 注意:preventDefault() 必须放在函数最开始,且确保该事件监听器能捕获到点击(推荐使用事件委托 $(document).on(...),尤其适用于动态生成的按钮)。
方案二:将测试按钮改为 type="button"
从根本上消除歧义,语义更清晰:
<!-- 主提交按钮(保持 type="submit") --> <button type="submit">保存模板</button> <!-- 测试按钮(改为 type="button",无默认提交行为) --> <button id="test-template" type="button">预览效果</button>
此时无需 event.preventDefault(),点击 #test-template 将只触发 click 事件,完全不会干扰表单 submit 流程。
? 额外建议
- 统一数据类型:两个 AJAX 请求都应显式声明 dataType: "json",避免因服务端响应头不一致导致解析异常。
-
错误处理不可省略:生产环境务必添加 error 回调,捕获网络失败或服务端异常:
error: function(xhr, status, err) { console.error("模板预览失败:", status, err); alert("预览失败,请检查网络或联系管理员"); } - 防重复提交:可在 submit 处理中临时禁用按钮(如 $(this).prop("disabled", true)),防止用户连点。
通过明确按钮语义或主动拦截默认行为,即可彻底隔离两种操作路径,让「提交」与「预览」各司其职,保障前端逻辑的可预测性与健壮性。


















