如何使用promise、async-await等异步方法实现表单验证?
解决思路
原生HTML的onsubmit属性仅识别同步返回的布尔值,异步函数返回的Promise会被浏览器当作真值处理,不等异步结果返回就会触发默认提交行为,所以要做两层处理:
- 首次触发提交事件时直接阻止默认提交行为
- 异步校验全部通过后,手动调用表单的
submit()方法完成提交(手动调用submit()不会触发onsubmit事件,不会出现重复校验的死循环问题)
改后完整代码
<!DOCTYPE html> <html> <head> <title>Hello Javascript</title> <script type = "text/javascript"> // 校验函数改为async异步类型 async function validateForm() { const u = document.getElementById("username").value; const p = document.getElementById("password").value; const form = document.getElementById('loginForm'); const submitBtn = document.getElementById('submitBtn'); // 同步基础校验优先执行 if(u === "") { alert("请输入用户名"); return false; } if(p === "") { alert("请输入密码"); return false; } // 提交按钮加loading,避免重复点击 submitBtn.disabled = true; submitBtn.innerText = '校验中...'; try { // 示例:异步校验逻辑,可替换为实际的接口请求,比如校验用户名是否已注册 const asyncCheckPass = await new Promise((resolve) => { setTimeout(() => { // 此处写实际的异步校验规则,校验通过返回true,失败返回false resolve(u !== '已存在的用户名'); }, 1500) }) if (!asyncCheckPass) { alert('该用户名已被注册'); return false; } } catch (err) { alert('校验请求失败,请稍后重试'); return false; } finally { // 恢复按钮状态 submitBtn.disabled = false; submitBtn.innerText = '提交'; } alert("校验通过,正在提交数据!") // 异步校验全部通过,手动提交表单 form.submit(); return true; } </script> </head> <body> <h2>输入用户名和密码</h2> <div style="border:1px solid #ddd; padding: 5px;"> <!-- 给表单添加id方便获取DOM,onsubmit直接返回false阻止默认提交 --> <form id="loginForm" method="POST" action="process-action.html" onsubmit = "validateForm(); return false;"> 用户名: <input type="text" name="username" id="username"/> <br><br> 密码: <input type="password" name = "password" id="password"/> <br><br> <button id="submitBtn" type="submit">提交</button> </form> </div> </body> </html>
额外注意事项
- 如果不想在
onsubmit属性里写固定返回false,也可以通过addEventListener绑定submit事件,在事件回调里调用e.preventDefault()阻止默认提交,逻辑完全一致 - 异步校验过程中建议禁用提交按钮,避免用户多次点击触发多次校验请求
内容的提问来源于stack exchange,提问作者geekdu972
相关产品推荐
相关产品推荐

