PHP框架中加CORS头需在响应对象设置Access-Control-Allow-Origin等字段,Laravel可在中间件实现;注意*与credentials不能共存,预检请求需路由支持OPTIONS,反代时需在Nginx/Apache配置头,跨域传Cookie需精确Origin、credentials: 'include'及SameSite=None+Secure。

PHP 框架里怎么加 CORS 响应头
直接在响应对象上设置 Access-Control-Allow-Origin 等头部,是最常见也最可控的方式。不同框架写法略有差异,但核心逻辑一致:请求进来后、响应发出前,补上跨域所需头信息。
以 Laravel 为例,在中间件中写:
public function handle($request, Closure $next)
{
$response = $next($request);
$response->headers->set('Access-Control-Allow-Origin', '*');
$response->headers->set('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE');
$response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
$response->headers->set('Access-Control-Allow-Credentials', 'true');
return $response;
}
注意:* 和 Access-Control-Allow-Credentials: true 不能共存,若前端带 withCredentials,后端必须指定具体域名,比如 https://example.com。
为什么 OPTIONS 预检请求总是 405 或 500
浏览器对非简单请求(如带 Authorization 头、Content-Type 为 application/json)会先发一个 OPTIONS 请求。如果路由没配或控制器没处理,就直接 405(Method Not Allowed);如果中间件没放行或抛了异常,可能 500。
立即学习“PHP免费学习笔记(深入)”;
- 确保路由支持
OPTIONS方法,Laravel 可用Route::options()显式声明 - 部分框架(如 ThinkPHP)默认不解析空体的
OPTIONS请求,需在中间件中提前返回 200 并终止后续流程 - 不要依赖前端“只发 POST”,浏览器会自动插一个
OPTIONS,后端必须接住
Apache / Nginx 反代时 CORS 头被吃掉了怎么办
当 PHP 应用跑在反向代理后面(比如 Nginx 转发到 php-fpm),代理层可能覆盖或忽略 PHP 设置的响应头。这时候得在 Web 服务器配置里补全,而不是只靠 PHP 写。
Nginx 示例(加在 location 块内):
add_header 'Access-Control-Allow-Origin' '$http_origin' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
关键点:always 参数保证即使 PHP 返回了 4xx/5xx,头也不会被丢;$http_origin 动态取值比硬写 * 更安全;return 204 是最稳妥的预检响应方式。
前后端联调时 Cookie 或 token 总是传不过去
这通常不是 CORS 配置漏了,而是几个细节卡住了:
- 前端 fetch 必须显式加
credentials: 'include'(axios 是withCredentials: true) - 后端
Access-Control-Allow-Origin不能为*,必须是精确匹配的协议+域名+端口,例如https://admin.example.com:3000 - PHP 的
session.cookie_samesite默认是Lax,跨域请求下会阻止 Cookie 发送;可在php.ini或运行时设为None,同时必须开启session.cookie_secure(即只走 HTTPS) - 如果是 JWT 存在 localStorage,那和 CORS 无关;但若存在
HttpOnlyCookie 里,就严格依赖上述配置
真正难调的不是加头,而是 Origin 值是否动态、Cookie 是否被 SameSite 拦截、预检是否被代理吞掉——这些地方一错,现象都是“请求发出去了,但拿不到数据”。











