一次因表单默认提交导致的白屏排查记录
最近在做补充耕地踏勘评价系统时,遇到了一次非常“诡异”的问题:在提交采样记录表时,页面突然卡在“正在提交中”的 loading状态,然后白屏,界面自动刷新,控制台没有任何报错。起初以为是前端逻辑里哪里抛出了未捕获的异常,于是加上了全局的 window.onerror
和 unhandledrejection
捕捉,还开启了 Chrome 的 Preserve log 功能,但结果依然没有任何报错信息,只能看到一堆正常的打印和最后的页面跳转。为了追踪问题,我开始逐行排查代码,甚至怀疑过是 Capacitor 的原生插件调用不稳定,或者是 Quasar 的对话框逻辑有 bug,直到后来才发现问题的根源其实非常简单——表单的默认提交行为。
在 Vue 或 Quasar 中,我们习惯写 <form>
标签并用 <q-btn type="submit">
来触发表单提交。但在原生 HTML 里,submit
按钮会触发浏览器的默认表单提交流程,直接刷新整个页面,将表单内容提交到 action
指定的地址。如果 action
没写,就会提交到当前路径,从而导致整页刷新。我的代码里虽然写了 @click="submitSamplingAndSurvey"
,但因为按钮仍然是 type="submit"
,浏览器执行默认行为的优先级比 Vue 的事件还高,结果页面直接刷新,Vue 应用被销毁重建,就出现了白屏加重新挂载的情况。
这也解释了为什么控制台里没有报错,因为浏览器刷新本身并不是错误,而是正常的行为。至于“卡在提交中的 loading”,那是因为刚进入提交逻辑时就设置了加载状态,但还没等方法真正执行,页面已经刷新掉了,loading 也就被迫定格在那一瞬间。
意识到这一点后,解决方法就非常明确了。要么在 <form>
上加上 @submit.prevent="submitSamplingAndSurvey"
,用 Vue 的事件修饰符显式阻止浏览器的默认提交行为;要么把按钮的 type
改成 "button"
,单纯通过点击事件来触发提交逻辑,而不让它走原生表单提交流程。这两种方法都能彻底解决白屏和页面刷新的问题。回过头来看,这其实是个很经典的“表单默认提交坑”,在开发单页应用时特别容易被忽略,因为我们大多数时候只关注 Vue 里的逻辑,忘了浏览器的基础机制依旧生效。好在这次排查过程虽然曲折,但也算是一个很好的提醒——遇到奇怪的白屏或刷新,不一定就是框架或依赖的问题,有时最底层的 HTML 行为才是关键。