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

前端一旦发起携带 Authorization 头或 Content-Type: application/json 的请求,浏览器会自动先发送一个 OPTIONS 预检请求。若该预检返回 405 或没有任何响应,真实请求就会被阻止。问题根源在于 ThinkPHP 8.0 未正确处理此预检请求,或返回的响应头缺少必要字段。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
通过命令行生成中间件文件: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 验证中间件可能提前输出响应,导致头信息已发送错误。
当前端设置了 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');
方法一:使用 curl 手动触发预检请求:
curl -I -X OPTIONS http://your-domain.com/api/v1/users
检查响应中是否包含 Access-Control-Allow-Origin 以及状态码是否为 204。
方法二:在 Chrome 开发者工具的 Network 标签页中,筛选 OPTIONS 请求,点击查看 Response Headers 区域。
如果看到 HTTP/2 404 或 HTTP/2 500,说明路由未匹配到 OPTIONS 方法,这不是中间件的问题,而是路由层缺少对 OPTIONS 路径的处理。
方法三:临时在中间件 handle 开头添加一行 file_put_contents('/tmp/cors.log', "OPTIONS hit\n", FILE_APPEND);,然后发起跨域请求,检查日志是否写入——若能写入,说明中间件已执行,失败点在于 header 设置或响应返回环节。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述