为何这份简单的PHP文件无法正常启用CORS?
解决Apache+PHP的CORS跨域问题(提示Access-Control-Allow-Origin缺失)
嘿,我来帮你搞定这个CORS坑!你已经在PHP里加了正确的响应头,但还是触发错误,大概率是OPTIONS预检请求没处理好——这是跨域请求里最容易被忽略的点,我之前也踩过这个坑。下面给你一步步的解决方案:
1. 先处理OPTIONS预检请求(最关键!)
浏览器发送跨域GET/POST请求前,会先发送一个OPTIONS预检请求,确认服务器允许跨域。如果你的PHP没正确响应这个OPTIONS请求,后续的真实请求就会被拦截。修改你的index.php:
<?php // 优先处理OPTIONS预检请求 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { // 设置CORS响应头 header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Credentials: true"); header("Access-Control-Max-Age: 1000"); header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Cache-Control, Pragma, Authorization, Accept, Accept-Encoding"); header("Access-Control-Allow-Methods: PUT, POST, GET, OPTIONS, DELETE"); // 直接结束响应,不需要返回任何内容 exit(0); } // 处理GET/POST等真实请求 header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Credentials: true"); header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Cache-Control, Pragma, Authorization, Accept, Accept-Encoding"); header("Access-Control-Allow-Methods: PUT, POST, GET, OPTIONS, DELETE"); echo('CORS activated!!!'); ?>
注意:OPTIONS请求只需要返回响应头,必须用exit(0)终止脚本,避免输出额外内容干扰响应。
2. 确认Apache的mod_headers模块已开启
如果Apache没启用mod_headers,即使PHP设置了header也可能不生效:
- 打开Apache主配置文件(比如
httpd.conf或apache2.conf) - 找到
#LoadModule headers_module modules/mod_headers.so,去掉前面的#注释 - 重启Apache服务
3. 尝试直接在Apache配置里设置CORS(更稳定)
有时候PHP的header会因为输出缓冲、字符编码等问题失效,直接在Apache里配置更可靠:
方式一:修改主配置文件
找到你的PHP文件所在目录的<Directory>配置块,添加以下内容:
<Directory "/path/to/your/php/files"> Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Methods "PUT, POST, GET, OPTIONS, DELETE" Header set Access-Control-Allow-Headers "X-Requested-With, Content-Type, Origin, Cache-Control, Pragma, Authorization, Accept, Accept-Encoding" Header set Access-Control-Allow-Credentials "true" Header set Access-Control-Max-Age "1000" # 自动响应OPTIONS请求 RewriteEngine On RewriteCond %{REQUEST_METHOD} OPTIONS RewriteRule ^(.*)$ $1 [R=200,L] </Directory>
方式二:用.htaccess文件(无主配置权限时)
在你的项目根目录创建.htaccess文件,写入:
Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Methods "PUT, POST, GET, OPTIONS, DELETE" Header set Access-Control-Allow-Headers "X-Requested-With, Content-Type, Origin, Cache-Control, Pragma, Authorization, Accept, Accept-Encoding" Header set Access-Control-Allow-Credentials "true" Header set Access-Control-Max-Age "1000" RewriteEngine On RewriteCond %{REQUEST_METHOD} OPTIONS RewriteRule ^(.*)$ $1 [R=200,L]
配置完记得重启Apache。
4. 检查PHP文件的输出问题
如果你的index.php开头<?php之前有空格、空行或其他字符,会导致header无法设置(因为header必须在任何输出之前)。确保文件开头没有任何多余字符!
5. 用浏览器网络面板排查
打开Firefox开发者工具(F12)→ 网络标签,刷新页面后查看:
- 是否有OPTIONS请求,它的响应头里有没有
Access-Control-Allow-Origin - 真实的GET请求的响应头是否包含该字段
按上面的步骤来,基本就能解决你的问题了!先试第一步处理OPTIONS请求,这是最常见的原因。
内容的提问来源于stack exchange,提问作者Roby Sottini
相关产品推荐
相关产品推荐

