PHP接口跨域请求失败完整解决方案(Access-Control-Allow-Origin 报错根治)
PHP接口跨域请求失败完整解决方案(Access-Control-Allow-Origin 报错根治)
内容定位:实战干货、场景化讲解、通俗易懂,适配头条号流量规则,适合前后端开发者、接口开发人员学习,覆盖前端Ajax、Vue、小程序请求PHP接口所有跨域场景,独家梳理多场景报错与适配方案。
在前后端分离开发模式下,PHP作为后端接口服务,对接前端网页、小程序、APP、Vue/React项目时,跨域请求报错是最高频的问题。浏览器控制台提示:No 'Access-Control-Allow-Origin' header is present on the requested resource,接口请求失败、数据无法返回,后端无任何报错,前端直接请求异常。
很多新手开发者只会复制网上通用的跨域代码,解决简单场景,但遇到多域名跨域、带Cookie跨域、OPTIONS预请求、HTTPS跨域等复杂场景,依旧报错无法解决。本文结合线上真实接口项目,从零讲解跨域原理、各类场景错误写法、针对性解决方案,覆盖99%PHP接口跨域场景。

一、跨域报错核心场景
- 本地前端localhost请求线上PHP接口跨域失败
- 小程序、APP请求PHP接口跨域拦截
- 前端携带Cookie、Token请求,跨域配置失效
- 多域名访问同一后端接口,部分域名跨域报错
- POST复杂请求触发OPTIONS预请求,接口404/403报错
二、新手高频错误跨域代码(治标不治本)
全网最泛滥的错误通用写法,仅能解决最简单的GET无参请求,复杂场景全部失效:
该写法存在两大致命问题:
第一,通配符 * 不支持携带Cookie、Token、自定义请求头的跨域请求,是绝大多数业务接口跨域失败的核心原因;
第二,全站开放所有域名跨域,存在严重的网站安全漏洞,容易引发CSRF攻击。
三、跨域底层原理通俗讲解
跨域并非后端接口限制,而是浏览器的同源安全策略限制。浏览器会拦截非同源的前端请求,只有后端返回合法的跨域响应头,浏览器才会放行请求。
简单请求(GET、简单POST)仅校验域名;复杂请求(携带Header、Cookie、JSON参数)会先发送OPTIONS预请求校验权限,预请求失败则直接拦截正式请求。很多开发者忽略OPTIONS请求处理,导致接口明明正常,却始终跨域报错。
四、全场景适配解决方案(可直接上线使用)
单域名精准跨域(生产环境首选,安全合规)
指定允许跨域的前端域名,支持Cookie、Token携带,适配所有请求方式:
多域名动态跨域(适配多前端场景)
项目对接多个前端域名时,动态校验请求来源,精准放行合法域名,兼顾灵活性与安全性:
<?php
// 定义允许跨域的域名白名单
$allow_domain = [
'https://a.xxx.com',
'https://b.xxx.com',
'http://localhost:8080'
];
// 获取请求来源
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
// 匹配白名单域名,放行跨域
if(in_array($origin,$allow_domain)){
header('Access-Control-Allow-Origin: '.$origin);
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Headers: Content-Type,Authorization,Token');
header('Access-Control-Allow-Methods: GET,POST,OPTIONS');
}
// 处理OPTIONS预请求,直接终止程序
if($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
exit('ok');
}
?>
- 接口全局跨域配置(框架/大型项目通用)
将跨域配置封装为公共文件,在接口入口统一引入,无需每个接口单独配置,统一全局规范,避免遗漏。
五、线上跨域避坑核心要点
- 生产环境禁止使用 * 通配符,不仅无法适配带凭证的请求,还存在严重安全风险;
- 所有复杂接口必须处理OPTIONS预请求,否则浏览器持续拦截;
- 前端携带Cookie跨域时,前端代码必须开启 withCredentials 配置,前后端配合才能生效;
- 跨域响应头必须写在接口逻辑最前端,前置输出、报错终止都会导致跨域配置失效;
- HTTPS站点禁止放行HTTP域名跨域,避免混合内容报错与安全漏洞。
六、前后端配套前端关键配置
Ajax原生请求配置:
var xhr = new XMLHttpRequest();
xhr.withCredentials = true; // 开启凭证携带
Vue Axios配置:
axios.defaults.withCredentials = true;
只有前后端同时配置,带Cookie、Token的跨域请求才能100%正常通行。
友情链接
凡尘博客
凡尘博客文章|凡尘博客文摘
凡尘影院
凡尘乡音|凡尘街坊
凡尘博客|雨落凡尘博客|羽落凡尘博客
凡尘博客|雨落凡尘博客|羽落凡尘博客
版权声明
本文为凡尘(雨落凡尘、羽落凡尘)原创技术文章,采用 CC BY-NC-ND 4.0 协议,禁止未授权商业转载与二次修改,转载需注明作者与原文链接。