PHP不创建虚拟目录,跨域需通过设置CORS响应头解决;必须在脚本开头用header()设置Access-Control-Allow-Origin等头,并拦截OPTIONS预检请求返回204,禁用框架method_filter,生产环境应动态校验Origin白名单。

PHP本身不创建“虚拟目录”,所谓虚拟目录是Web服务器(如Nginx或Apache)的配置概念;PHP只负责处理请求并输出响应头。跨域问题的根源在浏览器同源策略,解决核心是正确设置CORS响应头,并确保预检请求(OPTIONS)被及时响应——不是靠目录映射,而是靠HTTP头与请求流程控制。
必须在PHP脚本开头设置响应头
最直接有效的方式是在每个接口脚本(或统一入口如index.php、API路由分发处)顶部添加header()调用,且必须早于任何输出(包括空格、BOM、echo、HTML):
- 允许指定前端域名:header('Access-Control-Allow-Origin: https://your-app.com');
- 允许多个方法:header('Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE');
- 声明前端实际发送的请求头:header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
- 如需传Cookie或Token,必须开启凭证支持:header('Access-Control-Allow-Credentials: true');此时Access-Control-Allow-Origin不能为*,必须写具体域名。
必须显式响应OPTIONS预检请求
浏览器对非简单请求(如带Authorization头、Content-Type为application/json、使用PUT/DELETE等)会先发OPTIONS请求。若PHP不拦截并快速返回200/204,真实请求根本不会发出:
- 在脚本最开始加判断:if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(204); exit; }
- 不要写成
return或echo ''后继续执行,必须exit或die终止流程 - ThinkPHP等框架需禁用method_filter,或把OPTIONS加入白名单,否则框架自身会直接返回405
生产环境建议动态校验Origin
硬编码* 或固定域名存在安全风险或灵活性不足。可结合白名单做简单校验:
- 定义允许的来源数组:
$allowed_origins = ['https://admin.example.com', 'https://app.example.com']; - 获取当前请求头:
$origin = $_SERVER['HTTP_ORIGIN'] ?? ''; - 匹配后设置:
if (in_array($origin, $allowed_origins)) { header("Access-Control-Allow-Origin: $origin"); } - 同时仍需设置
Access-Control-Allow-Credentials: true和其它配套头
注意Web服务器与PHP头的协作关系
Nginx/Apache配置的add_header与PHP的header()会叠加,但有覆盖规则:
- PHP中header()默认会覆盖同名服务器头(除非Nginx用了
always修饰) - 常见陷阱:Nginx配了
add_header Access-Control-Allow-Origin *;,PHP又写了具体域名——最终以PHP为准 - 反向代理场景下,确认Nginx未过滤Origin头,也未因缓存或CDN吞掉CORS响应头
- 推荐Nginx仅作兜底,关键逻辑由PHP控制,更可控、可调试
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











