直接在PHP入口文件开头拦截OPTIONS请求并返回204响应,设置完整CORS头后立即exit,是最轻量、兼容性最强的方式;生产环境推荐Nginx层提前拦截以提升性能与稳定性。

直接在PHP脚本开头拦截OPTIONS
最轻量、兼容性最强的方式:在入口文件(如index.php)或所有接口统一入口处,第一行就判断请求方法。只要检测到OPTIONS,立即返回204并终止执行。
- 用$_SERVER['REQUEST_METHOD'] === 'OPTIONS'判断,不能依赖框架路由后再处理
- 必须调用http_response_code(204)或直接header('HTTP/1.1 204 No Content'),不能用200
- 响应体必须为空——连换行、空格、BOM都不允许,否则Safari等浏览器会拒绝后续请求
- 所有header()调用必须放在exit之前,且不能有任何echo、print或输出缓冲干扰
动态设置CORS头,避免凭据冲突
带credentials: 'include'(如Cookie、Authorization)的请求,Access-Control-Allow-Origin绝不能设为*,否则浏览器直接拦截。必须根据请求头中的Origin做白名单校验。
- 读取$origin = $_SERVER['HTTP_ORIGIN'] ?? ''
- 预定义允许列表:$allowed = ['https://admin.example.com', 'http://localhost:3000']
- 仅当$origin在列表中,才设置header("Access-Control-Allow-Origin: $origin")和header('Access-Control-Allow-Credentials: true')
- 不匹配时,可不设Allow-Origin头,让浏览器自然报错,不泄露白名单信息
配合Nginx更稳妥(推荐生产环境)
PHP层处理OPTIONS容易受框架路由、中间件顺序、输出污染影响。Nginx提前拦截,既快又稳,PHP只专注业务响应。
- 在server或location块中单独写if ($request_method = 'OPTIONS') { ... return 204; }
- add_header全部加always参数,否则204响应不带CORS头
- PHP只需在正常请求(GET/POST等)中动态加头,逻辑更清晰、更少出错
- 这样即使某条路由没被PHP捕获,Nginx也已兜底响应预检,不会出现405或404卡死
ThinkPHP 8等框架的注意事项
框架自带的跨域功能(如allowCrossDomain()或CorsMiddleware)需严格按生命周期执行,否则无效。
立即学习“PHP免费学习笔记(深入)”;
- 中间件必须注册在middleware.php数组最前面,确保最早拦截OPTIONS
- Route::group()->allowCrossDomain()要链式调用在分组末尾,且第二个参数true表示启用凭据,漏掉会导致前端静默失败
- 若用Swoole/Workerman,不能用header()函数,必须统一走$response->header()
- 配置paths时别写['*'],应限定为['api/*']等实际接口路径,避免暴露管理后台



















