配置CORS后AJAX仍遇跨域错误,请求排查解决方法
问题根源与解决方案
你的问题出在浏览器预检请求(OPTIONS)未被正确处理。因为你发送的POST请求设置了Content-Type: application/json,属于非简单请求,浏览器会先自动发送OPTIONS请求到目标服务器,确认是否允许跨域。你的原有PHP代码没有专门处理OPTIONS请求,导致预检请求的响应中缺少CORS头,从而触发错误。
修复后的PHP代码
<?php // 优先处理OPTIONS预检请求 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET, POST, OPTIONS'); header('Access-Control-Allow-Headers: Content-Type, Accept'); header('Access-Control-Max-Age: 86400'); // 缓存预检结果1天,减少重复请求 exit(0); } // 处理正常业务请求 header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET, POST, OPTIONS'); header('Access-Control-Allow-Headers: Content-Type, Accept'); // 你的业务逻辑 if(1) { echo 1; } ?>
关键注意事项
- 必须优先处理OPTIONS请求:预检请求不需要执行业务逻辑,返回CORS头后直接退出脚本即可,避免后续输出干扰头信息。
- 确保无前置输出:检查PHP文件开头是否有空格、换行或UTF-8 BOM(隐形字符),这些会导致
header()函数失效(PHP要求头必须在任何输出之前发送)。 - 服务器配置检查:如果修改后仍报错,确认你的服务器(Apache/Nginx)是否允许OPTIONS请求被PHP处理。比如Apache需要确保
.htaccess或配置文件中没有拦截OPTIONS请求;Nginx需要在location块中添加if ($request_method = OPTIONS) { return 204; }(或让请求转发到PHP)。
AJAX代码小优化
你的AJAX代码中setRequestHeader多了个冗余逗号,建议修正:
const hashdata = {json : JSON.parse(sessionStorage.getItem("user"))['hashdata']}; var xhr = new XMLHttpRequest(); xhr.open("POST", "http://example.com/chat/login.php", true); xhr.setRequestHeader('Accept', 'application/json'); // 去掉末尾冗余逗号 xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); xhr.send(JSON.stringify(hashdata)); xhr.onload = function() { console.log(this.responseText); }
内容的提问来源于stack exchange,提问作者Merlin the Immortal
相关产品推荐
相关产品推荐

