You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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")
          
        }
    }
}); 

解决方案

问题根源有两个:

  1. 验证阶段未统一邮箱大小写,导致unique校验失效,直接走到数据库保存环节触发SQL错误;
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:44:58