Ajax请求出错时重生成CSRF Token 解决Laravel表单无刷新二次提交问题
问题原因
Laravel默认会在每次请求校验(尤其是CSRF校验、表单验证)完成后重新生成CSRF Token,首次提交出错后旧Token已经失效,但页面meta标签存储的还是最初的旧Token,导致第二次提交时携带的Token不匹配。
解决方案
1. 后端调整:错误响应返回新Token
你可以选择两种方式实现,选其中一种即可:
- 方式一:修改注册控制器逻辑,验证失败时附带上新生成的CSRF Token
// 注册方法内的验证逻辑示例 $validator = Validator::make($request->all(), [ // 你的表单验证规则 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:8|confirmed', ]); if ($validator->fails()) { return response()->json([ 'errors' => $validator->errors(), 'new_csrf_token' => csrf_token() ], 422); }
- 方式二:全局配置异常处理器,所有JSON请求验证失败都自动返回新Token
修改app/Exceptions/Handler.php文件:
public function render($request, Throwable $exception) { if ($exception instanceof \Illuminate\Validation\ValidationException && $request->expectsJson()) { return response()->json([ 'errors' => $exception->errors(), 'new_csrf_token' => csrf_token() ], $exception->status); } return parent::render($request, $exception); }
2. 前端调整:错误回调更新本地存储的Token
修改你的JS代码,在请求错误时更新meta标签内的Token值,下次提交就会自动读取新的有效Token:
$(document).ready(function() { // 把全局Ajax配置提到点击事件外部,避免重复执行 $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); $('#send_form').click(function(e) { e.preventDefault(); $('#send_form').html('提交中..'); /* 通过ajax提交表单数据*/ $.ajax({ url: "{{ route('register')}}", method: 'POST', data: $('#ajax-register-form').serialize(), success: function(response) { $('#send_form').html('提交'); document.getElementById("ajax-register-form").reset(); // 提交成功也可同步更新Token,避免后续其他请求出错 if (response.new_csrf_token) { $('meta[name="csrf-token"]').attr('content', response.new_csrf_token); } }, error: function(data) { var errors = data.responseJSON; console.log(errors); $('.error-warning').show(); $('#send_form').html('提交'); // 核心逻辑:用后端返回的新Token更新本地meta标签 if (errors.new_csrf_token) { $('meta[name="csrf-token"]').attr('content', errors.new_csrf_token); } } }); }); });
内容的提问来源于stack exchange,提问作者Muhammad Shahzaib
相关产品推荐
相关产品推荐

