AJAX注册表单出现首个错误后无法校验后续必填项的问题
问题
我开发了一个AJAX注册表单,提交时如果仅填写gender字段,表单不会提示下一个必填项的错误——只要出现第一个错误就会停止提交,无法继续校验后续字段。表单在第一个错误弹出后就像卡住了一样,请问哪里出错了?
前端JS代码
//submit account and password register second part (account) $(document).ready(function(){ $("#register_second_part").on("submit", function(e){ console.log("TEST1"); e.preventDefault(); var token = $("#g-recaptcha-response").val(); var gender = $(".gender:checked").val(); var firstname = $('#name').val(); var lastname = $('#lastname').val(); var country = $(".countrySelect").find("option:selected").text(); var streetname = $('#streetname').val(); var streetnumber = $('#streetnumber').val(); var zipcode = $('#zipcode').val(); var city = $('#city').val(); var date = $('#date').val(); var phone = $('#phone').val(); var email = $('#second-email').val(); var password = $('#passwordForRegistration').val(); $.ajax({ url: "register_account_and_password_ajax.php", type: "POST", data: { email: email,new_password: password,gender:gender,name:firstname,lastname:lastname,country:country, streetname:streetname,streetnumber:streetnumber,zipcode:zipcode,city:city,date:date,phone:phone,recaptcha:token}, dataType: 'json', success: function (data) { if(data.type == 'success') { console.log("TEST2"); $('#registerSpamMessage').modal(); $('#registerSpamMessage').on('hidden.bs.modal', function () { $('#submitAccountRegister').html( "<span class='spinner-border spinner-border-sm' role='status' aria-hidden='true'></span> Laden..." ); window.location='products.php'; }); } else if(data.type == 'error') { console.log("TEST3"); $("#message2").html("<div class='alert alert-danger resizeFont' style='text-align:center;'>"+data.text+"</div>"); // grecaptcha.reset(); $(window).scrollTop(0); } } }); }); });
按钮代码
<button id="submitAccountRegister" type="submit">Click</button>
后端PHP校验代码片段
//See if gender is chosen if (!isset($_POST['gender'])) { array_push($errors, ""); $output = json_encode(array('type' => 'error', 'text' => "Choose your gender please")); die($output); } //see if country is chosen if($_POST["country"] == 'Select Country'){ array_push($errors, ""); $output = json_encode(array('type' => 'error', 'text' => "Choose your country please")); die($output); } if (empty($_POST['name']) || empty($_POST['lastname']) || empty($_POST['streetname']) || empty($_POST['streetnumber']) || empty($_POST['city']) || empty($email) || empty($_POST['new_password'])) { array_push($errors, ""); $output = json_encode(array('type' => 'error', 'text' => "All fields are required to fill in except your Birth date, Zip code or phone number")); die($output); } if ( strlen($_POST['name']) > 80 || strlen($_POST['lastname']) > 80 || strlen($_POST['streetname']) > 80 || strlen($_POST['city']) > 80 || strlen($_POST['new_password'] ) > 80) { array_push($errors, ""); $output = json_encode(array('type' => 'error', 'text' => "For fields: Firstname, Lastname, Streetname, City and Password are a max of 80 characters allowed")); die($output); } if(strlen($_POST['streetnumber']) > 15) { array_push($errors, ""); $output = json_encode(array('type' => 'error', 'text' => "For field Streetnumber is a max of 15 characters allowed")); die($output); } if(strlen($email) > 250) { array_push($errors, ""); $output = json_encode(array('type' => 'error', 'text' => "For field Email is a max of 250 characters allowed")); die($output); } if($_POST['date'] && strlen($_POST['date']) > 10) { array_push($errors, ""); $output = json_encode(array('type' => 'error', 'text' => "For field Birthdate is a max of 10 characters allowed")); die($output); }
问题原因与解决方案
核心问题
你的后端代码在每个校验分支里都使用了die($output),这个函数会立即终止PHP脚本的执行。也就是说,只要遇到第一个校验不通过的情况,脚本就直接返回错误信息并停止运行,后续所有的校验逻辑都不会被执行,自然无法发现并返回后续的错误。
解决方案
不要在单个校验失败时就终止脚本,而是先把所有错误信息收集到一个数组里,等所有校验逻辑执行完毕后,再判断是否存在错误:
- 如果没有错误,执行注册成功的逻辑;
- 如果有错误,把所有错误信息返回给前端(可以合并成一条提示,或者返回错误数组让前端逐个展示)。
修改后的后端PHP代码示例
$errors = []; //See if gender is chosen if (!isset($_POST['gender'])) { $errors[] = "Choose your gender please"; } //see if country is chosen if($_POST["country"] == 'Select Country'){ $errors[] = "Choose your country please"; } // 必填字段校验 $requiredFields = ['name', 'lastname', 'streetname', 'streetnumber', 'city', 'new_password']; $requiredMissing = false; foreach($requiredFields as $field) { if(empty($_POST[$field])) { $requiredMissing = true; break; } } if($requiredMissing) { $errors[] = "All fields are required to fill in except your Birth date, Zip code or phone number"; } // 字段长度校验(80字符限制) $max80Fields = ['name', 'lastname', 'streetname', 'city', 'new_password']; $overLength80 = false; foreach($max80Fields as $field) { if(strlen($_POST[$field]) > 80) { $overLength80 = true; break; } } if($overLength80) { $errors[] = "For fields: Firstname, Lastname, Streetname, City and Password are a max of 80 characters allowed"; } if(strlen($_POST['streetnumber']) > 15) { $errors[] = "For field Streetnumber is a max of 15 characters allowed"; } if(strlen($email) > 250) { $errors[] = "For field Email is a max of 250 characters allowed"; } if($_POST['date'] && strlen($_POST['date']) > 10) { $errors[] = "For field Birthdate is a max of 10 characters allowed"; } // 最后统一处理错误或成功 if(!empty($errors)) { // 去重后用换行分隔多个错误 $errorText = implode("<br>", array_unique($errors)); $output = json_encode(array('type' => 'error', 'text' => $errorText)); } else { // 这里执行注册成功的逻辑,比如写入数据库等 $output = json_encode(array('type' => 'success')); } echo $output; exit;
前端适配(可选)
如果后端返回多个错误,你可以保持现有前端逻辑不变,因为已经用<br>分隔了错误信息,会自动换行展示:
else if(data.type == 'error') { console.log("TEST3"); $("#message2").html("<div class='alert alert-danger resizeFont' style='text-align:center;'>"+data.text+"</div>"); $(window).scrollTop(0); }
内容的提问来源于stack exchange,提问作者Giovanni Paez
相关产品推荐
相关产品推荐

