首页 > 编程语言 >ThinkPHP8.0 CORS中间件处理跨域预检请求

ThinkPHP8.0 CORS中间件处理跨域预检请求

来源:互联网 2026-07-15 19:32:03

ThinkPHP8.0需创建CORS中间件,拦截OPTIONS预检请求并返回204状态码,设置跨域响应头。中间件必须置于middleware.php文件首位。当请求携带凭证时,禁止使用通配符星号,需通过白名单校验请求来源,动态设置Access-Control-Allow-Origin头部,否则浏览器会拦截后续真实请求。

ThinkPHP 8.0 跨域预检失败需配置 Cors 中间件:拦截 OPTIONS 请求返回 204 并设置 Access-Control 响应头,中间件须置于 middleware.php 数组首位;带 credentials 时禁止用 *,需白名单校验 origin 并动态设置响应头。

ThinkPHP8.0 CORS中间件处理跨域预检请求

前端一旦发起携带 Authorization 头或 Content-Type: application/json 的请求,浏览器会自动先发送一个 OPTIONS 预检请求。若该预检返回 405 或没有任何响应,真实请求就会被阻止。问题根源在于 ThinkPHP 8.0 未正确处理此预检请求,或返回的响应头缺少必要字段。

长期稳定更新的攒劲资源: >>>点此立即查看<<<

创建并注册 Cors 中间件

通过命令行生成中间件文件:php think make:middleware Cors

打开 app/middleware/Cors.php,将 handle 方法替换为以下代码:

if ($request->isOptions()) {
    return response('', 204)
        ->header('Access-Control-Allow-Origin', $request->header('origin') ?: '*')
        ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
        ->header('Access-Control-Allow-Headers', 'Authorization, Content-Type, X-Requested-With')
        ->header('Access-Control-Allow-Credentials', 'true');
}
$response = $next($request);
$response->header('Access-Control-Allow-Origin', $request->header('origin') ?: '*');
$response->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
$response->header('Access-Control-Allow-Headers', 'Authorization, Content-Type, X-Requested-With');
$response->header('Access-Control-Allow-Credentials', 'true');
return $response;

必须将 Cors::class 放在 app/middleware.php 数组的最前面,否则 SessionMiddleware 或 JWT 验证中间件可能提前输出响应,导致头信息已发送错误。

处理带凭证(Cookie/Auth)的跨域请求

当前端设置了 credentials: 'include' 时,浏览器会报错:“Credentials flag is true, but the 'Access-Control-Allow-Origin' value is not the literal '*'”——这是硬性限制,无法绕过。

第一步:禁止使用通配符 * 作为 Access-Control-Allow-Origin 的值。

第二步:动态读取 Origin 请求头,并仅允许白名单中的域名通过:

$origin = $request->header('origin');
$allowedOrigins = ['https://admin.example.com', 'http://localhost:3000'];
$origin = in_array($origin, $allowedOrigins)  $origin : null;

第三步:仅当 $origin 不为 null 时设置响应头,否则不返回任何 CORS 头,避免暴露敏感策略。

第四步:显式启用凭据支持:$response->header('Access-Control-Allow-Credentials', 'true');

验证 OPTIONS 预检是否真正生效

方法一:使用 curl 手动触发预检请求:

curl -I -X OPTIONS http://your-domain.com/api/v1/users

检查响应中是否包含 Access-Control-Allow-Origin 以及状态码是否为 204

方法二:在 Chrome 开发者工具的 Network 标签页中,筛选 OPTIONS 请求,点击查看 Response Headers 区域。

如果看到 HTTP/2 404HTTP/2 500,说明路由未匹配到 OPTIONS 方法,这不是中间件的问题,而是路由层缺少对 OPTIONS 路径的处理

方法三:临时在中间件 handle 开头添加一行 file_put_contents('/tmp/cors.log', "OPTIONS hit\n", FILE_APPEND);,然后发起跨域请求,检查日志是否写入——若能写入,说明中间件已执行,失败点在于 header 设置或响应返回环节。

侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述

热游推荐

更多
湘ICP备14008430号-1 湘公网安备 43070302000280号
All Rights Reserved
本站为非盈利网站,不接受任何广告。本站所有软件,都由网友
上传,如有侵犯你的版权,请发邮件给xiayx666@163.com
抵制不良色情、反动、暴力游戏。注意自我保护,谨防受骗上当。
适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。