自定义changePassword函数实现Ajax表单提交,默认GET请求无法阻止
问题分析与解决方案
你的代码里有几个关键问题导致e.preventDefault()无法生效,表单还是会发起默认的GET请求,我们一步步拆解并修复:
核心问题点
this指向错误:直接调用changePassword函数时,this指向的是全局对象(浏览器里是window),而非你要操作的表单元素。所以$(this).serializeArray()拿不到表单数据,this.submit(...)也是给window绑定提交事件,完全和目标表单无关。- 数据序列化时机错误:你在绑定事件之前就序列化了
data,这时候用户还没输入最新的表单内容,拿到的是初始空值或旧数据,毫无意义。 - 事件绑定逻辑颠倒:你在函数内部给某个元素绑定submit事件,但这个函数本身没有被作为表单的submit事件处理函数触发,所以当表单真正提交时,你写的
e.preventDefault()根本没机会执行。
修正后的代码方案
我们把函数改成适合作为表单submit事件处理函数的形式,确保this指向表单,并且在事件触发时才序列化最新数据:
方案一:直接作为事件处理函数
function changePassword(e, url) { // 第一步就阻止默认提交行为,放在最前面 e.preventDefault(); // 此时this就是触发事件的表单元素 const $form = $(this); // 序列化表单的最新数据 const data = $form.serializeArray(); $.post({ url: url, data: data, success(response) { switch(response) { case 'doesntMatch': Materialize.toast(`Die Passwörte stimmen nicht überein`, 4000); break; case 'success': Materialize.toast(`Passwort erfolgreich geändert`, 4000); // 可选:重置表单 $form[0].reset(); break; default: Materialize.toast(`Unbekannte Antwort vom Server`, 4000); } }, error() { Materialize.toast(`Ein Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.`, 4000); } }); }
然后在DOM加载完成后,给目标表单绑定事件:
$(document).ready(function() { // 替换成你的表单ID和实际接口URL $("#SomeId").submit(function(e) { changePassword.call(this, e, "/api/change-password"); }); });
方案二:封装成事件处理函数生成器(更优雅)
如果需要给多个表单绑定类似逻辑,可以封装一个生成器函数:
function createChangePasswordHandler(url) { // 返回一个可以直接作为submit事件处理函数的函数 return function(e) { e.preventDefault(); const data = $(this).serializeArray(); $.post({ url: url, data: data, success(response) { switch(response) { case 'doesntMatch': Materialize.toast(`Die Passwörte stimmen nicht überein`, 4000); break; default: Materialize.toast(`Passwort erfolgreich aktualisiert`, 4000); } } }); }; } // 绑定事件 $(document).ready(function() { $("#SomeId").submit(createChangePasswordHandler("/api/change-password")); });
额外注意事项
- 确保jQuery和Materialize都已经正确加载,没有加载顺序问题。
- 如果表单有
action属性,不用担心,只要e.preventDefault()执行了,就不会触发默认的表单提交。 - 可以考虑在
e.preventDefault()后添加e.stopPropagation(),防止事件冒泡到父元素(一般情况下不需要,但特殊场景有用)。
内容的提问来源于stack exchange,提问作者user9554056
相关产品推荐
相关产品推荐

