最推荐用中间件设置Access-Control-Allow-Origin,需校验Origin白名单、响应OPTIONS预检并注册为全局首个中间件。

ThinkPHP跨域配置中,用中间件设置 Access-Control-Allow-Origin 是最推荐、最可控的方式。它能精准拦截请求、处理预检(OPTIONS)、动态匹配来源,且不干扰框架响应生命周期。
为什么不能直接用 header() 函数?
在 ThinkPHP 6+ 中,手动调用 header() 很容易被后续响应流程覆盖,尤其在使用 Swoole 或 Workerman 时会完全失效。必须通过 $response->header() 方式操作 Response 对象,确保头信息写入最终响应体。
中间件里怎么安全设置 Access-Control-Allow-Origin?
关键在于:不硬编码 *,尤其当前端携带 Cookie 或 Authorization 时,Access-Control-Allow-Origin 必须与请求头中的 Origin 完全一致,且需同步设置 Access-Control-Allow-Credentials: true。
将 WCAG 2 AA 无障碍标准应用于设计系统、UI 组件和网页——通过可运行的验证器进行对比度计算,采用设计 token 模式使颜色天生可访问,设定排版和焦点状态规则,并提供语义检查清单。适用于构建或审查 UI。
- 先获取原始请求的 Origin:
$origin = $request->header('origin'); - 校验是否在白名单内(生产环境必须做):
in_array($origin, ['https://admin.example.com', 'http://localhost:8080']) - 只对合法来源设置响应头:
'Access-Control-Allow-Origin' => $origin - 若启用凭证,必须加:
'Access-Control-Allow-Credentials' => 'true',此时 Origin 不能为*
必须处理 OPTIONS 预检请求
浏览器发起带自定义头(如 Authorization)或非简单方法(PUT/DELETE)的跨域请求前,会先发一个 OPTIONS 请求。中间件若不响应它,就会卡住或返回 405 错误。
立即学习“PHP免费学习笔记(深入)”;
- 在 handle 方法开头判断:
if ($request->isOptions()) { return response('', 204); } - 204 状态码表示“无内容”,符合 CORS 预检规范,且不触发后续逻辑
- 不要用
return $next($request)处理 OPTIONS,否则可能抛异常或返回 500
中间件注册位置很重要
中间件执行顺序直接影响 CORS 头是否生效。它必须放在全局中间件数组的最前面,确保最早介入、最晚结束。
- 打开
app/middleware.php - 把中间件类完整命名空间(如
app\middleware\CorsMiddleware::class)加到数组首位 - 避免和其他中间件(如日志、鉴权)顺序颠倒,否则响应头可能被覆盖


















