Laravel 9中Mailable重复发送邮件问题(预期仅发送一次)
Laravel 9 审核系统重复发送邮件问题排查与解决
我使用Laravel 9开发了管理员审核玩家的系统,审核通过时需向玩家发送网站准入通知邮件。当管理员点击页面的「Aceptar(接受)」按钮后,请求进入Evaluations控制器,若审核值为3则触发邮件发送,但部分用户反馈收到多份重复邮件。
相关代码
控制器代码(EvaluationsController)
public function update(Request $request, $id) { $evaluation = Evaluation::findOrFail($id); $evaluation->approved = $request->approved; $evaluation->save(); if($evaluation->approved == 3) { $user = User::findOrFail($evaluation->idUser); $user->evaluation = 1; $user->save(); Mail::to($user->email)->send(new EvaluationMailable()); } return view('admin.evaluaciones'); }
视图代码
<form method="POST" action="{{route('evaluation.update',$evaluaciones->id)}}"> @csrf <input type="text" name="approved" value="3" hidden> <button type="submit" class="btn btn-primary bg-primary">Aceptar</button> @method('PUT') </form>
重复邮件截图

重复邮件原因分析
- 用户重复点击按钮:管理员可能多次快速点击「Aceptar」按钮,导致多次提交PUT请求,每次请求都会触发邮件发送。
- 无提交反馈导致误操作:页面提交后没有即时反馈(如按钮置灰、状态提示),用户可能误以为提交失败而再次点击。
- 后端状态校验缺失:当前代码未校验审核记录是否已处理过,即使
approved已经是3,再次提交仍会执行邮件发送逻辑。 - 页面刷新重复提交:提交后直接返回视图,用户刷新页面会重新触发请求。
解决方案
1. 前端禁用重复点击
在表单提交时立即禁用按钮,避免用户重复操作:
<form method="POST" action="{{route('evaluation.update',$evaluaciones->id)}}" onsubmit="handleSubmit()"> @csrf <input type="text" name="approved" value="3" hidden> <button type="submit" id="submitBtn" class="btn btn-primary bg-primary">Aceptar</button> @method('PUT') </form> <script> function handleSubmit() { const btn = document.getElementById('submitBtn'); btn.disabled = true; btn.textContent = '处理中...'; } </script>
2. 后端增加状态校验
执行邮件逻辑前,先判断审核记录是否未被处理过,避免重复触发:
public function update(Request $request, $id) { $evaluation = Evaluation::findOrFail($id); // 仅当当前状态不是3,且请求要设置为3时才执行邮件逻辑 if ($evaluation->approved !== 3 && $request->approved == 3) { $evaluation->approved = 3; $evaluation->save(); $user = User::findOrFail($evaluation->idUser); $user->evaluation = 1; $user->save(); Mail::to($user->email)->send(new EvaluationMailable()); } else { $evaluation->approved = $request->approved; $evaluation->save(); } // 重定向到列表页,避免刷新重复提交 return redirect()->route('evaluation.index')->with('success', '审核已完成'); }
3. 用重定向替代返回视图
提交成功后重定向到审核列表页面,防止用户刷新页面重复提交请求。
内容的提问来源于stack exchange,提问作者Francisco Flores
相关产品推荐
相关产品推荐

