Laravel 5.6中如何为所有API资源自动启用OPTION请求方法
Laravel 5.6 批量为API资源路由启用OPTIONS并解决CORS预检失败问题
针对你大量使用Route::apiResource且需要全局启用OPTIONS方法、解决CORS预检报错的问题,给你两个可行方案,优先推荐第一种,更简洁高效:
一、快速解决:全局OPTIONS路由+CORS中间件
这个方案不需要修改现有路由注册代码,直接全局处理:
1. 新建CORS中间件
执行命令生成中间件:
php artisan make:middleware Cors
打开app/Http/Middleware/Cors.php,替换内容为:
<?php namespace App\Http\Middleware; use Closure; class Cors { public function handle($request, Closure $next) { // 允许的前端域名,可替换为具体域名,比如['https://your-frontend.com'] $allowedOrigins = ['*']; $origin = $request->header('Origin'); $response = $next($request); // 设置跨域响应头 if (in_array($origin, $allowedOrigins) || empty($origin)) { $response->header('Access-Control-Allow-Origin', $origin ?? '*') ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS') ->header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); } // 处理OPTIONS预检请求,直接返回200 if ($request->isMethod('OPTIONS')) { return response('', 200)->withHeaders($response->headers->all()); } return $response; } }
2. 注册中间件到API组
打开app/Http/Kernel.php,在$middlewareGroups的api数组里添加CORS中间件:
protected $middlewareGroups = [ 'web' => [ // ... 原有内容不变 ], 'api' => [ 'throttle:60,1', 'bindings', \App\Http\Middleware\Cors::class, // 新增这一行 ], ];
3. 添加全局OPTIONS路由匹配
在routes/api.php最顶部添加:
// 匹配所有API路径的OPTIONS请求 Route::options('{all}', function () { return response('', 200); })->where('all', '.*');
二、自定义资源路由宏(可选)
如果你希望每个apiResource自动生成OPTIONS路由,可以用这种方式:
1. 扩展路由宏
打开app/Providers/RouteServiceProvider.php,在boot方法里添加:
use Illuminate\Routing\Router; public function boot() { parent::boot(); $this->app->extend('router', function (Router $router) { // 自定义带OPTIONS的apiResource宏 $router->macro('apiResourceWithOptions', function ($name, $controller, array $options = []) use ($router) { // 注册默认的API资源路由 $router->apiResource($name, $controller, $options); // 为每个资源路由添加OPTIONS方法 $resource = $router->getResource($name, $controller, $options); foreach ($resource->getRoutes() as $route) { $router->options($route->uri, "$controller@options")->name($route->getName() . '.options'); } }); return $router; }); }
2. 用新宏注册路由
在routes/api.php里替换原来的apiResource为自定义宏:
Route::apiResourceWithOptions('users', 'UserController'); Route::apiResourceWithOptions('posts', 'PostController'); // 其他资源路由同理
3. 控制器添加OPTIONS方法
创建一个基础API控制器App\Http\Controllers\Api\BaseController.php,让所有API控制器继承它:
<?php namespace App\Http\Controllers\Api; use Illuminate\Http\Response; use App\Http\Controllers\Controller; class BaseController extends Controller { public function options() { return response('', Response::HTTP_OK); } }
然后修改你的UserController等:
namespace App\Http\Controllers; use App\Http\Controllers\Api\BaseController; class UserController extends BaseController { // 原有控制器方法... }
额外检查:服务器配置
如果用Nginx部署,确保配置里允许OPTIONS请求,避免被服务器拦截:
location /api { if ($request_method = OPTIONS) { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods 'GET, POST, PUT, PATCH, DELETE, OPTIONS'; add_header Access-Control-Allow-Headers 'Content-Type, Authorization'; return 204; } // 其他原有配置(比如fastcgi_pass等) }
完成配置后重启服务器,Chrome的预检请求就会返回200状态码,同时携带正确的CORS头,解决拦截问题。
内容的提问来源于stack exchange,提问作者realtebo
相关产品推荐
相关产品推荐

