Ajax POST请求PHP文件遇CORS错误:缺失Access-Control-Allow-Origin头
解决跨域预检请求失败问题
针对你遇到的"Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present"错误,结合本地有效、线上无效的情况,给出以下解决思路:
1. 确保header()在任何输出前执行
PHP的header()必须在任何内容输出之前发送,包括空格、HTML标签、甚至文件开头的BOM字节。线上环境可能存在以下情况导致header失效:
calendar.dec.php或dbh.inc.php文件开头有前置空格或BOM(UTF-8带BOM格式会自动输出字节)dbh.inc.php中包含echo、print等输出语句
解决操作:
- 用编辑器打开所有相关PHP文件,确保
<?php是文件的第一行,前面无任何空格或字符 - 将文件编码改为
UTF-8无BOM格式 - 检查
dbh.inc.php中是否有提前输出内容的代码,移除或调整位置
2. 处理OPTIONS预检请求
浏览器发送POST请求前会先发送OPTIONS预检请求,你的当前代码仅处理POST请求,未响应OPTIONS,导致预检失败。需在PHP开头添加OPTIONS请求处理逻辑:
<?php header("Access-Control-Allow-Origin: *"); // 处理OPTIONS预检请求 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { header('Access-Control-Allow-Methods: POST, GET, OPTIONS'); header('Access-Control-Allow-Headers: Content-Type'); exit; } require 'dbh.inc.php'; session_start(); // 后续代码... ?>
3. 移除前端无效配置
你在Ajax中添加的以下配置是无效的,反而会导致问题,需删除:
dataType: 'jsonp':JSONP仅支持GET请求,与你的POST请求冲突- 前端设置
Access-Control-Allow-Origin头:该头是服务器端响应头,前端设置不生效
调整后的Ajax核心代码:
$.ajax({ type: 'post', url: 'includes/calendar.dec.php', data: {ajax: 1, sunday: sunday}, success: function(response){ // 你的处理逻辑... } });
4. 检查服务器是否限制自定义Header
部分共享主机可能禁用了PHP的header()函数,或有安全规则拦截自定义响应头。可通过以下方式验证:
- 在
calendar.dec.php最开头添加代码:<?php header("Access-Control-Allow-Origin: *"); echo "test"; exit; ?> - 用浏览器或调试工具请求该文件,查看响应头是否包含
Access-Control-Allow-Origin: * - 如果没有,说明服务器限制了header,可尝试通过.htaccess配置(仅适用于Apache服务器):
在项目根目录的.htaccess文件中添加:Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Methods "POST, GET, OPTIONS" Header set Access-Control-Allow-Headers "Content-Type"
5. 检查PHP错误日志
线上环境开启PHP错误日志,查看是否有headers already sent之类的错误,这类错误会直接导致header()调用失败,帮助定位具体问题。
内容的提问来源于stack exchange,提问作者Ishan Dutta
相关产品推荐
相关产品推荐

