Accept 这个头非常重要,决定了响应返回的格式,设置为 application/json
你遇到的所有报错,Laravel 会默认帮你处理为 Json 的格式。
但是这个头必须是客户端进行接口调用的时候设置,当有些时候客户端无法正确设置的时候,有没有办法默认就返回 Json 格式的响应呢。
其实我们可以添加一个中间件,给所有的 API 路由手动设置一下。
php artisan make:middleware ForceJsonResponse
app/Http/Middleware/ForceJsonResponse.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class ForceJsonResponse
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
// 强制为请求设置 Accept 头,以便在发生错误时也能返回 JSON 格式的响应
$request->headers->set('Accept', 'application/json');
return $next($request);
}
}
打开项目根目录下的 bootstrap/app.php 文件,找到 withMiddleware 部分,然后添加你的中间件。你可以选择将其添加为全局中间件,或者只为 api 路由组添加
<?php
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use App\Http\Middleware\ForceJsonResponse; // 引入中间件
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
// 将中间件添加到 'api' 中间件组的开头
$middleware->prependToGroup('api', [
ForceJsonResponse::class,
]);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
修改路由,抛出一个 403 错误测试一下。
routes/api.php
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
Route::prefix('v1')->name('api.v1.')->group(function () {
Route::get('version', function () {
abort(403, '这是一个权限不足的测试错误。');
return response()->json(['message' => 'this is version v1']);
})->name('version');
});
访问 xxxx.test/api/v1/version 。

现在在客户端无法正确设置 Accept 头的时候也能正常工作了,但是还是推荐所有客户端正确设置 Accept 头。