跨域资源共享:gh_mirrors/api1/api 配置 CORS 与 Preflight 请求处理
什么是跨域资源共享(CORS)?
跨域资源共享(Cross-Origin Resource Sharing,CORS)是一种浏览器安全机制,用于控制不同域名之间的资源访问。当前端应用(如 React、Vue)从一个域名请求另一个域名的 API 资源时,浏览器会触发 CORS 检查。如果服务器未正确配置 CORS,请求将被阻止,导致前端无法获取数据。
gh_mirrors/api1/api 作为 Laravel/Lumen 的 RESTful API 包,提供了灵活的跨域解决方案。本文将详细介绍如何在该项目中配置 CORS 策略,处理 Preflight 请求,并解决常见跨域问题。
CORS 配置基础
核心配置文件
CORS 相关设置主要通过项目的配置文件进行管理:
- 配置入口:config/api.php
在配置文件中,可通过中间件和响应头设置实现 CORS 控制。虽然配置文件中没有直接命名为 cors 的配置项,但可通过以下两种方式实现跨域支持:
方法一:通过中间件配置
在 middleware 数组中添加 CORS 中间件:
// config/api.php 第 156-158 行
'middleware' => [
\Barryvdh\Cors\HandleCors::class, // 添加 CORS 中间件
],
提示:如果项目中未包含
barryvdh/laravel-cors依赖,需先通过 Composer 安装:composer require barryvdh/laravel-cors
方法二:自定义响应头
在响应格式化类中添加 CORS 头信息:
// 可在 src/Http/Response/Format/Json.php 中添加
public function format(Request $request, $response)
{
$response->headers->set('Access-Control-Allow-Origin', '*');
$response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
$response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
// ... 其他格式化逻辑
}
Preflight 请求处理
什么是 Preflight 请求?
Preflight 请求是一种特殊的 OPTIONS 请求,浏览器在发送实际请求前会先发送该请求,以检查服务器是否允许跨域访问。Preflight 请求包含以下头部:
Access-Control-Request-Method:实际请求使用的 HTTP 方法Access-Control-Request-Headers:实际请求携带的自定义头部
处理流程
- 路由注册:为所有 API 路由添加 OPTIONS 方法支持
- 中间件处理:在 src/Http/Middleware/Request.php 中添加 Preflight 处理逻辑
// 示例代码:在 Request 中间件中处理 OPTIONS 请求
public function handle($request, Closure $next)
{
if ($request->isMethod('options')) {
$response = new \Illuminate\Http\Response();
$response->headers->set('Access-Control-Allow-Origin', '*');
$response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
$response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
return $response;
}
return $next($request);
}
高级配置:细粒度控制
限制允许的源域名
为提高安全性,建议限制允许的源域名,而非使用通配符 *:
// 在中间件中动态设置允许的源
$allowedOrigins = ['https://example.com', 'https://admin.example.com'];
$origin = $request->header('Origin');
if (in_array($origin, $allowedOrigins)) {
$response->headers->set('Access-Control-Allow-Origin', $origin);
}
支持凭据(Credentials)
如果 API 需要处理身份验证(如 cookies、JWT),需启用凭据支持:
// 设置允许凭据
$response->headers->set('Access-Control-Allow-Credentials', 'true');
// 注意:此时 Access-Control-Allow-Origin 不能为 *,必须指定具体域名
常见问题解决
问题 1:Preflight 请求 404
原因:未为 API 路由注册 OPTIONS 方法
解决方案:在路由定义时添加 OPTIONS 支持:
// 在路由注册文件中
$api->options('{all}', function() {
return response('', 204);
})->where('all', '.*');
问题 2:请求头不被允许
现象:控制台报错 Request header field xxx is not allowed by Access-Control-Allow-Headers
解决方案:在 Access-Control-Allow-Headers 中添加对应的请求头:
$response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
问题 3:带凭据的请求失败
现象:设置了 withCredentials: true 后请求被拒绝
解决方案:确保同时设置:
Access-Control-Allow-Credentials: trueAccess-Control-Allow-Origin为具体域名而非通配符
完整配置示例
以下是一个完整的 CORS 配置示例,结合了安全性和灵活性:
// config/api.php 中添加
'middleware' => [
\App\Http\Middleware\HandleCors::class,
],
// 自定义 CORS 中间件:app/Http/Middleware/HandleCors.php
<?php
namespace App\Http\Middleware;
use Closure;
class HandleCors
{
protected $allowedOrigins = [
'https://example.com',
'https://admin.example.com',
];
public function handle($request, Closure $next)
{
$origin = $request->header('Origin');
$allowedOrigin = in_array($origin, $this->allowedOrigins) ? $origin : '*';
// 处理 Preflight 请求
if ($request->isMethod('options')) {
$response = response('', 204);
} else {
$response = $next($request);
}
// 设置 CORS 头
$response->headers->set('Access-Control-Allow-Origin', $allowedOrigin);
$response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
$response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
$response->headers->set('Access-Control-Allow-Credentials', 'true');
$response->headers->set('Access-Control-Max-Age', '86400'); // 预检请求缓存时间(24小时)
return $response;
}
}
总结
通过本文的配置指南,你可以:
- 在 gh_mirrors/api1/api 项目中实现基础 CORS 支持
- 正确处理 Preflight 请求,确保复杂跨域请求正常工作
- 根据实际需求调整安全策略,平衡易用性和安全性
关键配置文件路径总结:
- 主配置文件:config/api.php
- 中间件目录:src/Http/Middleware/
- 响应格式化:src/Http/Response/Format/
如需进一步优化跨域性能,可考虑:
- 配置
Access-Control-Max-Age减少 Preflight 请求次数 - 使用 CDN 或反向代理(如 Nginx)处理跨域请求
- 针对特定路由单独配置 CORS 策略
希望本文能帮助你解决 gh_mirrors/api1/api 项目中的跨域问题,让前后端协作更加顺畅!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



