规范跨域代码,采用中间件的方式处理跨域

This commit is contained in:
柳清爽
2025-04-27 13:51:53 +08:00
parent ad60944f88
commit 71b2f12c77
7 changed files with 158 additions and 22 deletions

View File

@@ -63,17 +63,11 @@ class Api extends Controller
/**
* 跨域检测
* @deprecated 已由全局中间件 AllowCrossDomain 处理,此方法保留用于兼容
*/
protected function _checkCors()
{
// 允许跨域
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With, X-Token, X-Api-Token');
header('Access-Control-Max-Age: 1728000');
header('Access-Control-Allow-Credentials: true');
// 对OPTIONS请求直接返回
// 由全局中间件处理跨域,此处不再处理
if ($this->requestType === 'OPTIONS') {
Response::create()->send();
exit;

View File

@@ -26,22 +26,13 @@ class Auth extends Controller
/**
* 初始化
* 设置跨域相关响应头
*/
public function initialize()
{
parent::initialize();
// 允许跨域访问
header('Access-Control-Allow-Origin: ' . $this->allowOrigin);
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
// 由全局中间件处理跨域,此处不再处理
// 预检请求直接返回200
if (Request::method(true) == 'OPTIONS') {
exit();
}
// 初始化认证服务
$this->authService = new AuthService();
}

View File

@@ -0,0 +1,59 @@
<?php
namespace app\common\middleware;
/**
* 跨域请求中间件
*/
class AllowCrossDomain
{
/**
* 处理跨域请求
* @param \think\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, \Closure $next)
{
// 获取当前请求的域名
$origin = $request->header('origin');
// 当请求使用 credentials 模式时,不能使用通配符
// 必须指定具体的域名或提取请求中的 Origin
$allowOrigin = '*';
if ($origin) {
// 如果需要限制特定域名,可以在这里判断
// 以下是允许的域名列表,如果请求来自这些域名之一,则允许跨域
$allowDomains = [ /* */ ];
// 如果请求来源在允许列表中,直接使用该源
if (in_array($origin, $allowDomains)) {
$allowOrigin = $origin;
}
}
// 设置允许的请求头信息
$allowHeaders = [
'Authorization', 'Content-Type', 'If-Match', 'If-Modified-Since',
'If-None-Match', 'If-Unmodified-Since', 'X-Requested-With',
'X-Token', 'X-Api-Token', 'Accept', 'Origin'
];
$response = $next($request);
// 添加跨域响应头
$response->header([
'Access-Control-Allow-Origin' => $allowOrigin,
'Access-Control-Allow-Headers' => implode(', ', $allowHeaders),
'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Credentials' => 'true',
'Access-Control-Max-Age' => '86400',
]);
// 对于预检请求,直接返回成功响应
if ($request->method(true) == 'OPTIONS') {
return response()->code(200);
}
return $response;
}
}