Laravel注册页面邮箱验证失效,无法提示邮箱已占用
问题:注册页面邮箱重复验证提示失效,触发SQL唯一约束错误
开发的注册页面中,邮箱重复验证功能失效,提交已占用邮箱时无法弹出提示,反而触发SQL错误:
"message": "SQLSTATE[23505]: Unique violation: 7 ERROR: duplicate key value violates unique constraint "the_email"
DETAIL: Key (email)=(loremipsum@gmail.com) already exists.
成功注册时SweetAlert提示正常,但错误场景无反应。相关代码如下:
Controller 代码
public function registerUser(Request $request) { // Validate form input $validator = Validator::make($request->all(), [ 'first_name' => 'required', 'middle_name' => 'required', 'last_name' => 'required', 'birthdate' => 'required', 'email' => 'required|email|unique:user_models,email', 'password' => 'required|min:5|max:20' ], [ 'first_name.required' => 'First name field is required', 'middle_name.required' => 'Middle name field is required', 'last_name.required' => 'Last name field is required', 'birthdate.required' => 'Birthdate field is required', 'email.required' => 'Email field is required', 'email.email' => 'Email field should be a valid email', 'email.unique' => 'The email has already been taken', 'password.required' => 'Password field is required', 'password.min' => 'Password should be at least 5 characters', 'password.max' => 'Password should be at most 20 characters', ]); if ($validator->fails()) { // Return validation error if input is invalid return response()->json([ 'status' => 400, 'errors' => $validator->messages(), 'message' => 'Please fix the following errors:', ])->withErrors($validator)->with('error', 'Please fix the following errors:'); } else { // Create new user model and save to database $user = new UserModel(); $user->first_name = Str::ucfirst($request->input('first_name')); $user->middle_name = Str::ucfirst($request->input('middle_name')); $user->last_name = Str::ucfirst($request->input('last_name')); $user->ip_address = $request->ip('ip_address'); $user->birthdate = $request->input('birthdate'); $user->email = Str::lower($request->input('email')); $user->account_status = '1'; $user->password = Hash::driver('whirlpool')->make($request->password); $user->save(); $seq_id = $user->seq_id; $user->application_code ="AUP-M231-". str_pad($seq_id, 6, '0', STR_PAD_LEFT); $user->save(); // Create new ApplicantPPCModel and save to database $user2 = new ApplicantPPCModel(); $user2->email = Str::lower($request->input('email')); $user2->pc = $request->input('password'); $user2->seq_id = $user->seq_id; $user2->save(); // Send activation email to user $data = [ 'title' => 'Welcome to Lorem Ipsum University', 'body' => 'Thank you for registering with us', 'activation_code' => $user->application_code, 'first_name' => $user->first_name ]; try { Mail::to($user->email)->send(new MailNotify($data)); } catch (Swift_TransportException $e) { // Return error response if email fails to send return response()->json(['message' => 'Sorry! Please try again later'], 500); } // Return success response return response()->json([ 'status' => 200, 'message' => 'You have registered successfuly', ]); } }
Ajax 代码
$.ajax({ type: "POST", url: "/register-user", data: data, dataType: "json", success: function (response) { if(response.status == 400) { Swal.fire({ type: 'error', title: 'Oops...', text: 'That email is in use already. Please try another one', }) }else { $('.alert-success').removeClass('hideme'); setTimeout(function() { $('.alert-success').fadeOut(); }, 3000); $('#reg_first_name').val(''); $('#reg_middle_name').val(''); $('#reg_last_name').val(''); $('#reg_email').val(''); $('#birth_date').val(''); $('#reg_email_confirm').val(''); $('#reg_password').val(''); $('#reg_password_confirm').val(''); $('#reg_id_number').val(''); $("#checkbox-signup").prop("checked", false ); $("#btn-register").prop( 'disabled', true ); Swal.fire("You're Registered!", "Please check your email before proceeding to the Login Page", "success") } } });
解决方案
问题根源有两个:
- 验证阶段未统一邮箱大小写,导致
unique校验失效,直接走到数据库保存环节触发SQL错误; - Ajax未处理非200状态码的错误回调,SQL错误的500响应无法被捕获。
1. 修改Controller代码
- 在验证前统一邮箱为小写,确保和数据库存储格式一致,触发
unique校验; - 移除JSON响应中无效的
withErrors和with方法(这两个是给视图渲染用的,JSON响应不需要)。
修改后的Controller关键部分:
public function registerUser(Request $request) { // 先将邮箱转为小写,确保验证和存储格式一致 $request->merge(['email' => Str::lower($request->email)]); // Validate form input $validator = Validator::make($request->all(), [ // 验证规则不变 'first_name' => 'required', 'middle_name' => 'required', 'last_name' => 'required', 'birthdate' => 'required', 'email' => 'required|email|unique:user_models,email', 'password' => 'required|min:5|max:20' ], [ // 错误提示不变 'first_name.required' => 'First name field is required', 'middle_name.required' => 'Middle name field is required', 'last_name.required' => 'Last name field is required', 'birthdate.required' => 'Birthdate field is required', 'email.required' => 'Email field is required', 'email.email' => 'Email field should be a valid email', 'email.unique' => 'The email has already been taken', 'password.required' => 'Password field is required', 'password.min' => 'Password should be at least 5 characters', 'password.max' => 'Password should be at most 20 characters', ]); if ($validator->fails()) { // 移除withErrors和with,直接返回JSON并指定状态码 return response()->json([ 'status' => 400, 'errors' => $validator->messages(), 'message' => 'Please fix the following errors:', ], 400); } // 后续逻辑不变... }
2. 修改Ajax代码
- 添加
error回调处理500等错误状态; - 在success回调中根据返回的
errors动态获取提示信息,提升通用性。
修改后的Ajax代码:
$.ajax({ type: "POST", url: "/register-user", data: data, dataType: "json", success: function (response) { if(response.status == 400) { // 从返回的errors中获取邮箱重复的提示 let errorText = response.errors.email ? response.errors.email[0] : 'Please fix the following errors:'; Swal.fire({ icon: 'error', title: 'Oops...', text: errorText, }) }else { $('.alert-success').removeClass('hideme'); setTimeout(function() { $('.alert-success').fadeOut(); }, 3000); // 清空表单逻辑不变... $('#reg_first_name').val(''); $('#reg_middle_name').val(''); $('#reg_last_name').val(''); $('#reg_email').val(''); $('#birth_date').val(''); $('#reg_email_confirm').val(''); $('#reg_password').val(''); $('#reg_password_confirm').val(''); $('#reg_id_number').val(''); $("#checkbox-signup").prop("checked", false ); $("#btn-register").prop( 'disabled', true ); Swal.fire("You're Registered!", "Please check your email before proceeding to the Login Page", "success") } }, // 添加错误回调处理SQL等非预期错误 error: function(xhr) { let errorMsg = 'An error occurred. Please try again.'; if(xhr.responseJSON && xhr.responseJSON.message) { errorMsg = xhr.responseJSON.message; } Swal.fire({ icon: 'error', title: 'Error', text: errorMsg, }); } });
内容的提问来源于stack exchange,提问作者CaptainCRAZY
相关产品推荐
相关产品推荐

