JS表单校验调用fetch异步请求无法同步返回校验结果如何解决
表单异步校验同步返回结果的解决方案
JavaScript单线程运行机制决定了不存在既不阻塞主线程、又能同步返回异步请求结果的实现,你可以根据场景选择以下两种方案:
方案1:使用同步XMLHttpRequest(满足直接返回结果的要求,不推荐)
如果必须在onsubmit函数内同步返回校验结果,可以用兼容但已被规范废弃的同步XHR实现,请求过程中会阻塞页面UI交互,直到请求返回才会继续执行后续逻辑:
form.onsubmit = function() { let signInData = JSON.stringify(Object.fromEntries(new FormData(form).entries())); let flag = false; const xhr = new XMLHttpRequest(); // 第三个参数设为false开启同步模式 xhr.open('POST', 'php/sign_up.php', false); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(signInData); if(xhr.status === 200) { const data = xhr.responseText; if(data !== "1") { document.getElementById("sign_up_error").innerHTML = data; flag = false; } else { flag = true; } } return flag; };
方案2:状态标记二次触发(推荐,无阻塞)
不需要修改原有提交侧的调用逻辑,通过自定义属性标记校验状态,首次调用直接返回false,异步校验通过后手动加标记重走提交逻辑即可:
form.onsubmit = function() { // 校验通过的二次触发直接返回true if(this.hasAttribute('data-valid-pass')) { this.removeAttribute('data-valid-pass'); return true; } let signInData = JSON.stringify(Object.fromEntries(new FormData(form).entries())); fetch('php/sign_up.php', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: signInData, }) .then(response => response.text()) .then(data => { if(data !== "1") { document.getElementById("sign_up_error").innerHTML = data; } else { // 标记校验通过,重新触发原有提交逻辑 form.setAttribute('data-valid-pass', ''); if(form.onsubmit()) { sendFormData(); } } }); // 首次调用直接返回false,等待异步校验结果 return false; };
内容的提问来源于stack exchange,提问作者cherryguy
相关产品推荐
相关产品推荐

