Laravel中使用Ajax时如何处理认证中间件触发的重定向
Laravel下Ajax请求未登录场景处理方案
问题原因
默认认证逻辑对未登录请求直接返回302重定向到登录页,Ajax请求场景下浏览器会自动跟随该重定向,最终返回登录页的HTML内容,和代码里指定的dataType: 'json'预期格式不符,因此触发错误回调。
第一步:改造自定义认证中间件
在中间件的认证判断逻辑中,优先识别Ajax/JSON请求,这类请求不要返回重定向响应,直接返回401状态码的JSON格式错误提示:
public function handle($request, Closure $next) { if (!auth()->check()) { // 识别Ajax请求或期望返回JSON的请求 if ($request->ajax() || $request->wantsJson()) { return response()->json([ 'msg' => '登录状态已失效,请先登录' ], 401); } // 普通页面请求才执行重定向 return redirect()->route('login'); } return $next($request); }
第二步:优化前端Ajax错误处理逻辑
在error回调中按HTTP状态码做分支处理,专门捕获401未登录场景,做对应的提示和跳转,同时补上Laravel POST请求必须的CSRF请求头,避免419错误:
function addBasket(url) { var formData = { product_id: $("#addbasket").attr('value') } $.ajax({ data: formData, url: url, type: 'POST', dataType: 'json', headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, success: function (data) { data.forEach(el => { $("#count").text(el.count) }) console.log(data); }, error: function (xhr) { // 处理未登录场景 if (xhr.status === 401) { alert(xhr.responseJSON?.msg || '请先登录后再操作'); window.location.href = '/login'; return; } // 其他错误通用处理 alert('请求失败,请稍后重试'); console.log(xhr) } }) }
优化建议
- 提前在页面
<head>区域添加CSRF meta标签,供全局Ajax读取:<meta name="csrf-token" content="{{ csrf_token() }}"> - 如果项目中存在大量Ajax请求,可以配置全局Ajax错误监听,不用在每个请求的error回调里重复写401判断逻辑:
// 全局监听Ajax错误 $(document).ajaxError(function (event, xhr) { if (xhr.status === 401) { alert('登录状态已失效,即将跳转到登录页'); window.location.href = '/login'; } })
内容的提问来源于stack exchange,提问作者Abbas
相关产品推荐
相关产品推荐

