yii2中需在控制器behaviors()中配置corsfilter,origin不能为*且需与supportscredentials=true配合,yii1需手动设header并处理options路由。

Yii2 中 CorsFilter 怎么加到控制器里
直接在控制器类里声明 behaviors(),把 CorsFilter 塞进去就行。别漏掉 Content-Type 这类关键头的允许配置,否则预检请求(OPTIONS)会失败。
-
CorsFilter必须放在AuthMethod之类鉴权行为之前,否则 OPTIONS 请求可能被拦截 - 如果只对某个 action 开启跨域,用
'only' => ['index', 'view']限定,避免全控制器暴露 - 默认不放行
Credentials(比如 cookies),要支持登录态需显式设'supportsCredentials' => true,且前端fetch得配credentials: 'include' - 示例:
public function behaviors() { return [ 'cors' => [ 'class' => \yii\filters\Cors::className(), 'cors' => [ 'Origin' => ['https://example.com'], 'Access-Control-Request-Headers' => ['*'], 'Access-Control-Allow-Credentials' => true, ], ], ]; }
为什么本地开发用 * 允许 Origin 却还是报错
因为 Access-Control-Allow-Origin: * 和 Access-Control-Allow-Credentials: true 是互斥的。只要开了 credentials,Origin 就不能写 *,必须精确匹配(如 https://localhost:3000)。
- 开发时容易填成
'Origin' => ['*'],但 Yii 的CorsFilter会直接忽略这个配置,导致响应头没带Access-Control-Allow-Origin - 检查响应头:用浏览器 DevTools 看 Network → Response Headers,确认有没有
Access-Control-Allow-Origin字段 - 多域名调试建议用数组明确列出:
'Origin' => ['http://localhost:3000', 'http://127.0.0.1:3000'],别依赖通配
Yii1 怎么配 CORS(没有内置 CorsFilter)
Yii1 没 CorsFilter,得手动在入口脚本或控制器 init() 里输出响应头。注意顺序:头必须在任何输出前发送,否则 headers already sent 错误。
- 最简方式:在
index.php顶部加header('Access-Control-Allow-Origin: https://example.com'); header('Access-Control-Allow-Methods: GET, POST, OPTIONS'); header('Access-Control-Allow-Headers: Content-Type, Authorization'); - 如果用了 URLManager 或需要按路由控制,建议写个行为类继承
CAction,在run()前发 header - 特别注意:Yii1 默认把
OPTIONS请求当非法方法拦截,要在UrlManager配置里加'enableStrictParsing' => false,或单独路由映射options到空 action
预检请求(OPTIONS)返回 404 或 500 怎么查
Yii 默认不处理纯 OPTIONS 请求,除非你显式配置了对应 action 或行为捕获它。404 说明路由没匹配上,500 往往是 filter 初始化时报错(比如 Origin 配置语法错)。
- 先确认是否真发了 OPTIONS:DevTools 的 Network 标签页里筛选
Method = OPTIONS - 在
CorsFilter的beforeAction里加var_dump($this->cors['Origin']); die;,看配置是否被正确加载 - 常见坑:
'Origin' => 'https://a.com'写成字符串而非数组;'Access-Control-Allow-Headers'里写了不存在的 header 名(如X-Requested-With在某些前端库已弃用) - 生产环境 Nginx/Apache 可能提前拦截 OPTIONS,确认 Web 服务器没做额外限制
跨域真正麻烦的不是加几行配置,而是前后端 header 对不上、credentials 开关不一致、预检和实际请求分开调试——这些地方一错,错误信息往往藏在浏览器控制台最底下一行,得点开才看得见。











