Laravel 5.6 Ajax请求异常返回JSON而非HTML的调试方案咨询
恢复Laravel 5.6+ AJAX POST请求的HTML错误页面响应
我刚好遇到过这个问题,Laravel 5.6开始对AJAX请求的异常响应默认返回JSON格式,这是框架为适配前后端分离场景做的优化,但确实会打断依赖原生HTML错误页面的调试流程。下面给你两种可行的解决方案,推荐第一种,因为它更灵活且不会影响正常的AJAX成功响应:
方案一:修改全局异常处理器(推荐)
Laravel的异常响应逻辑都在app/Exceptions/Handler.php的render方法里,我们可以在这里添加判断,让开发环境下的AJAX请求也返回渲染后的HTML错误页面:
<?php namespace App\Exceptions; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Throwable; class Handler extends ExceptionHandler { // ... 其他默认代码 public function render($request, Throwable $exception) { // 先让框架完成基础的异常处理 $response = parent::render($request, $exception); // 仅在本地开发环境生效,避免生产环境暴露敏感错误信息 if (app()->environment('local') && $request->ajax() && $response instanceof \Illuminate\Http\JsonResponse) { $statusCode = $response->getStatusCode(); // 尝试渲染对应状态码的错误视图,找不到则用500错误页兜底 try { $errorView = view("errors::{$statusCode}", compact('exception'))->render(); } catch (\InvalidArgumentException $e) { $errorView = view('errors::500', compact('exception'))->render(); } // 返回HTML格式的错误响应 return response($errorView, $statusCode); } return $response; } }
修改完成后,你的AJAX请求在出错时就会返回和非AJAX请求一致的原生HTML错误页面了。
调整前端错误处理代码
把你的全局错误处理函数改回原来依赖responseText的逻辑即可:
function ajaxErrorGlobalFunction(xhr, status, error) { if (xhr.responseText) { openErrorWindow(xhr.responseText); } } function openErrorWindow(htmlContent = "") { var w = window.open('', '_blank', 'scrollbars=yes,status=yes,titlebar=yes'); $(w.document.body).html(htmlContent); w.resizeTo(1000, 1000); w.moveTo(0, 0); w.focus(); }
方案二:在AJAX请求中强制指定Accept头
如果不想修改后端代码,可以在AJAX请求里添加Accept: text/html头,告诉服务器你需要HTML格式的响应:
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'), 'Accept': 'text/html' // 添加这一行 } });
⚠️ 注意:这个方法会让所有AJAX请求都优先获取HTML响应,如果你有正常的AJAX请求需要返回JSON,这个方案会冲突,所以仅推荐在调试阶段临时使用。
内容的提问来源于stack exchange,提问作者D. Petrov
相关产品推荐
相关产品推荐

