php跨域需在响应前用header()设置四项关键cors头:origin校验、methods声明、headers白名单、credentials支持;开发用静态域名,生产须动态校验origin并匹配白名单,且options预检请求必须正确响应。

前端对接时PHP框架拼接CORS跨域响应头,必须在HTTP响应发出前完成header()调用,且要覆盖Origin校验、Methods声明、Headers白名单、Credentials支持四项关键字段,否则浏览器将直接拦截后续请求。
手动拼接基础响应头(开发调试首选)
这一步操作起来很简单,直接把header()语句写在PHP脚本最开头即可。
在入口文件或控制器方法顶部添加以下四行:
header("Access-Control-Allow-Origin: http://localhost:5173");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With");
header("Access-Control-Allow-Credentials: true");
【Access-Control-Allow-Origin不能为*,否则携带Cookie的请求会被浏览器静默拒绝】
动态校验Origin并拼接(生产环境必须)
静态写死域名无法适配多前端环境,必须从$_SERVER中提取真实请求源并比对白名单。
第一步:定义可信源数组,包含协议、域名、端口全量信息:
$allowed = ['https://admin.example.com', 'https://app.example.com', 'http://localhost:5173'];
第二步:获取并校验来源:
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (in_array($origin, $allowed)) {
header("Access-Control-Allow-Origin: $origin");
header('Vary: Origin');
}
第三步:无论是否匹配成功,都必须设置其余通用头:
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-API-Key");
第四步:仅当Origin匹配时才启用凭据支持:
if (in_array($origin, $allowed)) { header("Access-Control-Allow-Credentials: true"); }
处理OPTIONS预检请求并拼接响应头
浏览器对非简单请求会先发OPTIONS探路,PHP不响应则真实请求永远不会发出。
方法一:在所有业务逻辑前插入判断:
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header("Access-Control-Allow-Origin: " . ($_SERVER['HTTP_ORIGIN'] ?? '*'));
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With");
header("Access-Control-Max-Age: 86400");
exit;
}
方法二:更安全的写法——只对白名单源响应OPTIONS:
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';
if (in_array($origin, $allowed)) {
header("Access-Control-Allow-Origin: $origin");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Access-Control-Allow-Credentials: true");
}
http_response_code(200);
exit;
}
【header()必须在exit()之前执行,否则预检响应不完整,前端仍报错】
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











