yii2解决跨域必须避开wildcard+credentials冲突:启用access-control-allow-credentials=true时,origin须指定具体域名数组(如['http://localhost:8080']),不可用['*'];同时需显式配置options路由并确保请求进入yii生命周期。

最省事的解法不是“一招通吃”,而是按版本分清底线:Yii1.1靠手动 header;Yii2必须避开 wildcard + credentials 冲突;Yii3(实际指 Yii 3.0 alpha 阶段)已弃用 CorsFilter,改用 PSR-15 中间件——但目前生产环境极少用 Yii3,所以重点落在 Yii2。
Yii1.1:直接在控制器里写 header
它没有内置 CORS 过滤器,也不走行为(behavior)机制,最直白有效的方式就是手动输出响应头:
- 在 action 开头或 beforeAction() 里加:
header('Access-Control-Allow-Origin: http://localhost:8080'); - 如果带 cookie 或 token,再加:
header('Access-Control-Allow-Credentials: true'); - 预检请求(OPTIONS)要单独处理,可加一个空 action 并路由匹配:
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { exit; }
Yii2:用 CorsFilter 但必须配对严谨
别信“加个 * 就完事”,这是跨域失败最常见的坑。关键就三点:
-
Origin 不能写 ['*'],当
Access-Control-Allow-Credentials => true时,必须列明可信域名,比如['https://admin.example.com', 'http://localhost:8080'] -
OPTIONS 路由必须显式存在,否则 405 错误;可在 UrlManager 里加规则:
'options <controller:>/<action:>' => '<controller>/options'</controller></action:></controller:>,再在控制器里写空的 options 动作 - 认证失败(401/403)时 CORS 头不生效,因为过滤器在鉴权后才执行;解决办法是在自定义 auth 类(如继承 HttpBearerAuth)的 authenticate() 方法里,手动 set 响应头
Yii3(Alpha):用中间件,但不推荐上线用
Yii3 已移除 yii\filters\Cors,改用 nyholm/psr7 + 自定义中间件。示例结构如下:
- 写一个 PSR-15 中间件,在 handle() 里判断 origin、设置 header、放行 OPTIONS
- 需配合 DI 容器注册,并确保它在 auth 中间件之前执行
- 但截至 2026 年中,Yii3 仍无 LTS 版本,社区生态弱,文档少,线上项目基本不用——真要省事,不如退回 Yii2 稳定版
不复杂但容易忽略:跨域从来不是单点配置问题,而是前后端配合链。前端 fetch 要带 credentials: 'include',后端响应头 Origin 必须和前端 origin 完全一致(协议、端口、域名),缺一不可。











