Laravel 的默认错误处理器通过 Illuminate\Http\Request
的 expectsJson()
方法来决定是否将错误信息渲染成 JSON 格式输出。这要求将请求头的 Accept
字段设置为 application/json
。本文提供一种方法,在尽可能减少代码的情况下,强制让 api 路由组中的所有错误响应变成 JSON 格式,而不依赖于请求的 Accept
头部。
第一步,新建 ExpectsJson
中间件,内容如下:
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
class ExpectsJson
{
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param callable $next
* @return \Illuminate\Http\Response
*/
public function handle(Request $request, $next)
{
// force $request->expectsJson() return true
((function () {
$this->acceptableContentTypes = ['application/json'];
})->bindTo($request, Request::class))();
return $next($request);
}
}
第二步,启用该中间件。修改 app\Http\Kernel.php
文件:
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
... ...
'api' => [
... ...
\App\Http\Middleware\ExpectsJson::class, // 添加中间件到 api 组
],
];
... ...
/**
* The priority-sorted list of middleware.
*
* Forces non-global middleware to always be in the given order.
*
* @var array
*/
protected $middlewarePriority = [
\App\Http\Middleware\ExpectsJson::class, // 调整中间件顺序在 AuthenticatesRequests 之前
... ...
\Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class,
... ...
];
该方法的原理就是:利用闭包修改 Illuminate\Http\Request
的保护成员,使得 expectsJson()
方法返回 true。