本文目录导读:

在Laravel项目中配置跨域资源共享(CORS)有几种方法,以下是完整的配置指南:
方法1:使用Laravel内置CORS中间件(推荐)
Laravel 9+ 默认包含CORS支持,Laravel 7/8需要安装扩展包。
安装(Laravel 7/8)
composer require fruitcake/laravel-cors
发布配置文件(所有版本)
php artisan vendor:publish --tag=cors
配置 config/cors.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
|--------------------------------------------------------------------------
*/
'paths' => ['api/*', 'sanctum/csrf-cookie'], // 允许的路径
'allowed_methods' => ['*'], // 允许的HTTP方法
'allowed_origins' => ['*'], // 允许的来源(域名)
'allowed_origins_patterns' => ['*'], // 允许来源的正则表达式
'allowed_headers' => ['*'], // 允许的请求头
'exposed_headers' => [], // 暴露给客户端的响应头
'max_age' => 0, // 预检请求的缓存时间(秒)
'supports_credentials' => false, // 是否允许携带认证信息(cookies等)
];
具体配置示例
<?php
return [
'paths' => ['api/*', 'login', 'register'],
'allowed_methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
'allowed_origins' => [
'http://localhost:3000',
'http://localhost:5173',
'https://your-frontend.com',
],
'allowed_origins_patterns' => [
'http://*.example.com',
],
'allowed_headers' => [
'Content-Type',
'X-Requested-With',
'Authorization',
'X-CSRF-TOKEN',
'Origin',
'Accept',
],
'exposed_headers' => [
'X-Pagination-Current-Page',
'X-Pagination-Total',
],
'max_age' => 3600,
'supports_credentials' => true,
];
方法2:自定义中间件
如果需要对CORS进行更细粒度的控制,可以创建自定义中间件。
创建中间件
php artisan make:middleware Cors
中间件代码
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class Cors
{
public function handle(Request $request, Closure $next)
{
// 处理预检请求
if ($request->isMethod('OPTIONS')) {
return response('', 200)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With, Authorization, X-CSRF-TOKEN');
}
// 处理其他请求
$response = $next($request);
$response->headers->set('Access-Control-Allow-Origin', '*');
$response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS');
$response->headers->set('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With, Authorization, X-CSRF-TOKEN');
$response->headers->set('Access-Control-Max-Age', '3600');
return $response;
}
}
注册中间件
在 app/Http/Kernel.php 中:
protected $middlewareGroups = [
'web' => [
// ...
\App\Http\Middleware\Cors::class,
],
'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\App\Http\Middleware\Cors::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
方法3:全局中间件(适用于所有请求)
在 app/Http/Kernel.php 中添加全局中间件:
protected $middleware = [
// ...
\App\Http\Middleware\Cors::class,
];
方法4:控制器级别配置
在控制器构造函数或方法中设置:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class UserController extends Controller
{
public function getUser(Request $request)
{
$data = ['name' => 'John Doe'];
return response()->json($data)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
}
}
方法5:路由组配置
<?php
use Illuminate\Support\Facades\Route;
Route::group(['middleware' => ['cors']], function () {
Route::get('/api/users', 'UserController@index');
Route::post('/api/users', 'UserController@store');
// 其他需要CORS的路由
});
Nginx/Apache服务器配置
除了应用层配置,还需要确保服务器配置支持:
Nginx配置
location / {
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, X-Requested-With';
add_header 'Access-Control-Max-Age' '3600';
return 204;
}
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, X-Requested-With';
}
Apache配置
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With"
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
</IfModule>
配置验证
创建一个测试路由:
<?php
use Illuminate\Support\Facades\Route;
Route::options('/api/test-cors', function () {
return response()->json([], 204);
});
Route::get('/api/test-cors', function () {
return response()->json(['success' => true, 'message' => 'CORS配置成功']);
});
使用curl测试:
curl -H "Origin: http://localhost:3000" \
-H "Access-Control-Request-Method: GET" \
-X OPTIONS \
http://your-app.test/api/test-cors -v
注意事项
- 安全性:生产环境建议只允许特定的域名,避免使用通配符
- 凭据:如果使用 cookies 或认证信息,设置
supports_credentials为true - 缓存:合理设置
max_age减少预检请求次数 - 调试:使用浏览器的开发者工具检查CORS错误信息
- HTTPS:如果使用HTTPS,确保前端也是HTTPS协议
选择适合你项目的方法,建议使用Laravel内置的CORS配置(方法1),它提供了最灵活和安全的配置方式。