如何从 Laravel 控制器返回 AJAX 错误?
Posted
技术标签:
【中文标题】如何从 Laravel 控制器返回 AJAX 错误?【英文标题】:How to return AJAX errors from a Laravel controller? 【发布时间】:2016-05-21 15:34:08 【问题描述】:我正在使用 Laravel 5 构建一个 REST API。
在 Laravel 5 中,您可以继承 App\Http\Requests\Request
来定义在处理特定路由之前必须满足的验证规则。例如:
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
class BookStoreRequest extends Request
public function authorize()
return true;
public function rules()
return [
'title' => 'required',
'author_id' => 'required'
];
如果客户端通过 AJAX 请求加载相应的路由,BookStoreRequest
发现请求不满足规则,它会自动将错误作为 JSON 对象返回。例如:
"title": [
"The title field is required."
]
但是,Request::rules()
方法只能验证输入——即使输入有效,在请求已被接受并移交给控制器之后,也可能会出现其他类型的错误。例如,假设控制器出于某种原因需要将新书信息写入文件——但文件无法打开:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Http\Requests\BookCreateRequest;
class BookController extends Controller
public function store( BookStoreRequest $request )
$file = fopen( '/path/to/some/file.txt', 'a' );
// test to make sure we got a good file handle
if ( false === $file )
// HOW CAN I RETURN AN ERROR FROM HERE?
fwrite( $file, 'book info goes here' );
fclose( $file );
// inform the browser of success
return response()->json( true );
显然,我可以die()
,但这太丑了。我希望以与验证错误相同的格式返回我的错误消息。像这样:
"myErrorKey": [
"A filesystem error occurred on the server. Please contact your administrator."
]
我可以构建自己的 JSON 对象并返回它——但 Laravel 肯定支持这一点。
最好/最干净的方法是什么?或者有没有更好的方法从 Laravel REST API 返回运行时(而不是验证时)错误?
【问题讨论】:
你为什么不能做一个return response()->json( ['error'=>'Your custom message'] );
?
可以构建自定义json响应类
return response()->json()
会返回 200 OK。我想使用适当的非 200 响应代码(例如 500 Internal Server Error)。是的,我也可以手动编写代码——我只是假设 Laravel 已经提供了一种内置的、更结构化的方式来执行此操作。也许这是一个不正确的假设。
为此考虑github.com/dingo/api。
@greenie2600 :你得到解决方案了吗?
【参考方案1】:
您可以在 json 响应中设置状态码,如下所示:
return Response::json(['error' => 'Error msg'], 404); // Status code here
或者只是使用辅助函数:
return response()->json(['error' => 'Error msg'], 404); // Status code here
【讨论】:
使用 response() 函数,而不是 $response()【参考方案2】:您可以通过多种方式做到这一点。
首先,您可以通过提供状态码来使用简单的response()->json()
:
return response()->json( /** response **/, 401 );
或者,以更复杂的方式来确保每个错误都是 json 响应,您可以设置异常处理程序来捕获特殊异常并返回 json。
打开App\Exceptions\Handler
并执行以下操作:
class Handler extends ExceptionHandler
/**
* A list of the exception types that should not be reported.
*
* @var array
*/
protected $dontReport = [
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
NotFoundHttpException::class,
// Don't report MyCustomException, it's only for returning son errors.
MyCustomException::class
];
public function render($request, Exception $e)
// This is a generic response. You can the check the logs for the exceptions
$code = 500;
$data = [
"error" => "We couldn't hadle this request. Please contact support."
];
if($e instanceof MyCustomException)
$code = $e->getStatusCode();
$data = $e->getData();
return response()->json($data, $code);
这将为应用程序中抛出的任何异常返回一个 json。
现在,我们创建MyCustomException
,例如在app/Exceptions中:
class MyCustomException extends Exception
protected $data;
protected $code;
public static function error($data, $code = 500)
$e = new self;
$e->setData($data);
$e->setStatusCode($code);
throw $e;
public function setStatusCode($code)
$this->code = $code;
public function setData($data)
$this->data = $data;
public function getStatusCode()
return $this->code;
public function getData()
return $this->data;
我们现在可以只使用MyCustomException
或任何扩展MyCustomException
的异常来返回一个json 错误。
public function store( BookStoreRequest $request )
$file = fopen( '/path/to/some/file.txt', 'a' );
// test to make sure we got a good file handle
if ( false === $file )
MyCustomException::error(['error' => 'could not open the file, check permissions.'], 403);
fwrite( $file, 'book info goes here' );
fclose( $file );
// inform the browser of success
return response()->json( true );
现在,不仅通过MyCustomException
抛出的异常将返回 json 错误,而且任何其他一般抛出的异常都将返回。
【讨论】:
【参考方案3】:一个简单的方法是在控制器中使用abort()
方法。这将返回一个错误,该错误将被 ajax error:function()
控制器示例
public function boost_reputation(Request $request)
$page_owner = User::where('id', $request->page_owner_id)->first();
// user needs to login to boost reputation
if(!Auth::user())
toast('Sorry, you need to login first.','info');
abort();
// page owner cannot boost his own reputation
if(Auth::user() == $page_owner)
toast("Sorry, you can't boost your own reputation.",'info');
abort();
Ajax 示例
$('.reputation-btn').on('click',function(event)
var btn = this;
var route = " route('boost_reputation') ";
var csrf_token = ' csrf_token() ';
var id = ' $page_owner->id ';
$.ajax(
method: 'POST',
url: route,
data: page_owner_id:id, _token:csrf_token,
success:function(data)
...your success code
,
error: function ()
...your error code
);
);
更多信息:https://laravel.com/docs/7.x/errors
【讨论】:
以上是关于如何从 Laravel 控制器返回 AJAX 错误?的主要内容,如果未能解决你的问题,请参考以下文章
Laravel:为啥我的 ajax 请求返回“500(内部服务器错误)”?