<p>Yii2 CORS 配置需确保三点:预检请求(OPTIONS)被短路响应、凭证模式与 Origin 不冲突、响应头在生命周期内正确写入;全局配置须置于应用配置顶层,Origin 不能为 * 且需匹配 credentials,OPTIONS 请求需路由兜底,自定义请求头和暴露头须显式声明。</p>

Yii2 的 CORS 配置不是加个中间件就能跑通的事,关键在三点:预检请求(OPTIONS)必须被短路响应、凭证模式(withCredentials)和 Origin 不能冲突、响应头必须在 Yii 生命周期内正确写入。配错一处,浏览器就直接拦截,控制台报错但后端日志里看不出问题。
全局配置 cors 行为的位置很关键
很多人把 'as cors' 写进 components 或控制器的 behaviors() 里,结果不生效。正确做法是把它和 components、modules 并列,放在应用配置顶层:
- 在
config/web.php中,与'components' => [...]同级添加 - 确保
'class' => \yii\filters\Cors::className()被正确引用 - 如果只在某个控制器里配,要检查是否调用了
parent::behaviors(),否则会被覆盖
Origin 和 credentials 必须匹配
前端用了 credentials: 'include' 或 withCredentials: true,后端就不能写 'Origin' => ['*'] —— 浏览器会直接拒绝,哪怕响应头里写了 Access-Control-Allow-Origin: * 也没用。
- 必须明确列出可信域名,比如
['http://localhost:3000', 'https://admin.example.com'] - 如果开发阶段想省事,可临时关掉凭证:
'Access-Control-Allow-Credentials' => false,同时前端也去掉credentials - 生产环境严禁用
*配合true,这是安全硬性要求
OPTIONS 请求必须有兜底路由
浏览器发 PUT/DELETE 或带自定义 Header 的请求时,会先发 OPTIONS 预检。如果没配好路由,请求根本进不了 Yii,Cors 行为压根不会运行,直接 405 或 404。
- 在
urlManager的rules里加一条:'OPTIONS *' => 'site/options' -
SiteController::actionOptions()内只做两件事:设响应头 +Yii::$app->end(204) - 这个 action 里不能访问用户态、不能触发 beforeAction、不能输出任何内容
请求头和暴露头要显式声明
前端如果带了 Authorization、X-Auth-Token 这类自定义头,Access-Control-Request-Headers 就不能只写 ['*'] —— Yii2.0.45+ 对通配符支持有限,容易漏判。
- 建议写死:
['Content-Type', 'Authorization', 'X-Requested-With'] - 需要前端读取的响应头(如分页信息),得通过
Access-Control-Expose-Headers显式暴露 - Nginx 层不要重复加 CORS 头,否则可能冲突或触发“multiple values”错误



















