Ajax跨域失败本质是浏览器同源策略拦截,需后端正确配置CORS响应头并处理OPTIONS预检请求,PHP必须在任何输出前调用header()且Origin不能为*(若带Cookie)。

Ajax 调用失败,90% 不是 PHP 报错,而是浏览器直接拦了——跨域问题本质是浏览器的同源策略在起作用,PHP 只是“被要求配合放行”的一方。
为什么浏览器会拦你的 Ajax 请求?
同源策略只认三样东西:协议(http/https)、域名(a.com vs b.com)、端口(:80 vs :3000)。只要其中任一不同,哪怕只是 localhost 和 127.0.0.1,浏览器就认定跨域,自动加 Origin 头,并等待后端返回合法的 CORS 响应头才肯把数据交给你。
- 错误提示里出现
No 'Access-Control-Allow-Origin' header或preflight request doesn't pass access control→ 100% 是浏览器拦截,不是 PHP 崩了 -
cURL或 Postman 能通,但浏览器里fetch()或$.ajax()失败 → 确认是跨域机制生效,不是接口逻辑问题 -
前端发的是
PUT、带Authorization头、或Content-Type: application/json→ 浏览器必先发OPTIONS预检,后端没处理这个请求就会卡死,根本到不了你写的主逻辑
PHP 怎么加头才真正生效?
必须在任何输出(包括空格、BOM、echo、var_dump)之前调用 header(),否则会报 headers already sent。生产环境别用 *,要精确指定前端域名;如果前端带 Cookie,还得加 Access-Control-Allow-Credentials: true,且 Access-Control-Allow-Origin 不能为 *。
- 最简可用示例(开发阶段):
- 漏掉
OPTIONS处理 → 浏览器预检失败,后续请求压根不发 - 多个
header()调用顺序无所谓,但一旦有echo或空白字符在它前面,头就发不出去
怎么快速验证是不是 PHP 配置的问题?
用在线 PHP 环境(比如 phpsandbox.io)部署一个带 CORS 头的脚本,拿到公网 URL 后,直接在前端发起请求。这样能绕开本地环境干扰,快速区分问题是出在“PHP 没配对”,还是“前端代码写错了”或者“网络策略限制”。
立即学习“PHP免费学习笔记(深入)”;
- 前端用
fetch('https://xxx.phpsandbox.io/test.php'),看 Network 面板里响应头有没有Access-Control-Allow-Origin - 服务端加一句
error_log(print_r($_SERVER, true), 3, '/tmp/php-debug.log');可查实际收到的请求方法、头信息 - 如果连
OPTIONS请求都看不到 → 前端没触发跨域(比如用了代理),或请求根本没发出去(检查 URL 拼写、HTTPS 混合内容等)
真正难调试的,往往不是 CORS 头没加,而是 OPTIONS 返回了 404、没带头、或者和主请求的头不一致;还有就是前端带了 withCredentials: true,但后端 Access-Control-Allow-Origin 还写着 * —— 这种细节一漏,整个流程就静默失败。











