跨域最烦的不是"不会写",
而是------明明写了 CORS,还是不生效。
如果你也遇到过下面这些情况,这篇你基本对号入座了:
- PHP 接口本地 OK,上线就跨域
- 写了
Access-Control-Allow-Origin,浏览器还是拦 - AJAX 报错,cURL 却能请求成功
- Session / Cookie 在跨域后直接失效
- phpstudy、Nginx、Apache 表现完全不一样
这篇文章,不教"怎么配",只教你------怎么一步步把跨域问题揪出来。
一、第一步:先搞清楚"是谁在拦你"
❗ 90% 的跨域问题,根本不是 PHP 报错
你先记住一句话:
跨域错误,大多数是浏览器拦的,不是后端。
判断方法很简单:
1️⃣ 看浏览器控制台(不是 PHP 报错)
常见提示:
No 'Access-Control-Allow-Origin' headerCORS policy: Request blockedResponse to preflight request doesn't pass access control
👉 只要是这些,问题 100% 在跨域规则
2️⃣ 用 PHP cURL / Postman 测试接口
- cURL 能正常返回
- 浏览器 AJAX 不行
👉 直接确认:
接口逻辑没问题,是浏览器跨域机制在生效
二、第二步:确认是不是"真的跨域"
很多人以为自己跨域,其实不是。
对照一下是不是下面任意一种 👇
| 项目 | 只要不同就是跨域 |
|---|---|
| 协议 | http vs https |
| 域名 | api.xxx.com vs www.xxx.com |
| 子域 | a.xxx.com vs b.xxx.com |
| 端口 | :80 vs :8080 |
👉 localhost 和 127.0.0.1 也是跨域
三、第三步:判断是不是被 OPTIONS 预检卡死
什么时候浏览器会先发 OPTIONS?
满足任意一个:
- 使用
PUT / DELETE Content-Type不是application/x-www-form-urlencoded- 自定义请求头(token、authorization)
浏览器流程是:
OPTIONS 预检
↓
预检通过才会发真正请求
常见致命问题 ❌
- 后端没处理 OPTIONS
- OPTIONS 返回 404 / 500
- OPTIONS 没带 CORS 头
👉 结果:正式请求根本不会发
调试方法(非常关键)
在 Network 里:
- 看有没有 OPTIONS 请求
- 看状态码是不是 200
- 看 Response Headers 里有没有 CORS 头
四、第四步:检查 CORS 头是不是"完整且匹配"
很多人只写了这一行:
header("Access-Control-Allow-Origin: *");
然后就开始怀疑人生。
正确的检查清单 👇
1️⃣ 是否返回了 Access-Control-Allow-Origin
- 是否和请求域名一致
- 是否拼写正确
- 是否每个请求都返回(包括 OPTIONS)
2️⃣ 是否携带 Cookie / Session?
如果前端写了:
xhrFields: { withCredentials: true }
那你必须满足 三点同时成立:
Access-Control-Allow-Origin: https://xxx.com
Access-Control-Allow-Credentials: true
Set-Cookie: SameSite=None; Secure
👉 只要有一个不对,Cookie 就带不过去
五、第五步:Session 跨域失效的真实排查顺序
很多人卡在这里:
AJAX 能请求,但
$_SESSION永远是空的
别急,按顺序来:
✅ 排查顺序(非常重要)
- 浏览器是否真的带了 Cookie(Network → Request Headers)
- Cookie 是否被浏览器拦截(SameSite)
- 域名是否一致(子域要用
.xxx.com) - PHP
session.save_path是否正常 - 是否多台服务器导致 Session 不共享
👉 90% 的问题卡在第 2 步
六、第六步:分清 AJAX 跨域 和 cURL 跨域
这是很多人一辈子都没想通的点。
PHP cURL 为什么永远不跨域?
因为:
- cURL 是 服务器请求服务器
- 没有浏览器
- 不执行同源策略
- 不看 CORS
所以:
cURL 成功 ≠ AJAX 一定成功
正确的工程级解决方案
浏览器 AJAX
↓(同域)
自己 PHP 接口
↓(cURL)
第三方 API
👉 把跨域问题留在服务器内部解决
七、phpstudy / 本地环境的特殊坑
如果你用的是 phpstudy / 宝塔,很容易踩这些坑:
- Nginx 没加 OPTIONS 处理
- Apache
.htaccess没生效 - https 没配,Cookie 被拦
- 本地 hosts 和线上域名不一致
👉 本地 OK,线上挂,大多是环境差异
八、一个"万能调试模板"思路
当你彻底懵的时候,按这个流程走:
- 用浏览器看 Network(是不是 OPTIONS)
- 用 cURL / Postman 验证接口逻辑
- 对比 Request / Response Headers
- 单独处理 OPTIONS
- 再处理 Cookie / Session
不要同时改多个地方,一次只改一个点
九、配套完整跨域调试资源(源码级)
我把这些跨域问题整理成了一套可直接用的资源,包括:
- PHP CORS 基础 / 携带 Cookie
- Session 跨域完整示例
- AJAX / cURL 对照调试代码
- Nginx / Apache 配置
- phpstudy 特殊说明
👉 CSDN 下载地址: