Yii RESTful接口需正确配置Cors过滤器、使用HttpBearerAuth认证、继承yii\rest\Controller并设置Accept头为application/json,否则浏览器调用会因CORS、401或HTML响应失败。

Yii框架的RESTful接口完全适合Web端使用,但直接在浏览器中调用时必须处理好跨域、认证和响应格式三件事——否则会卡在 OPTIONS 预检失败、401 Unauthorized 或空响应上。
为什么浏览器发请求总被拦截(CORS问题)
Yii 默认不开启跨域支持,fetch 或 axios 从 http://localhost:3000 调 http://api.example.com/v1/users 会触发浏览器预检,而 Yii 返回的响应头里缺 Access-Control-Allow-Origin。
- 必须在配置中显式启用
Cors过滤器,不能只靠 Nginx/Apache 转发头 -
yii\filters\Cors要放在behaviors()里,且顺序不能在AuthMethod之后(否则未授权就拒绝了,连 CORS 头都不发) - 开发期可设
'Access-Control-Allow-Origin' => '*',但生产环境必须精确匹配前端域名,比如'https://app.example.com'
如何让登录态在 REST 接口和浏览器间一致
Yii 的 Web 应用默认用 session,但 REST 接口建议用无状态认证;强行复用 session 会导致 CSRF validation failed 或接口返回登录页 HTML。
- 不要在
UrlRule中混用web和api模块共用同一套User组件而不隔离认证方式 - 推荐方案:API 走
Bearer Token(用yii\filters\auth\HttpBearerAuth),Web 页面仍走 session,两者通过同一套UserIdentity验证逻辑 - 若必须共享 session,需关闭 API 控制器的
enableCsrfValidation = false,并在Request组件中设置'cookieValidationKey'一致
Content-Type 和 Accept 头不匹配导致返回 HTML
浏览器地址栏直接访问 /v1/users 会带 Accept: text/html,*/*,Yii 可能返回渲染后的 HTML 页面而非 JSON,尤其当控制器继承自 yii\web\Controller 而非 yii\rest\Controller 时。
- REST 接口控制器必须继承
yii\rest\Controller,不是yii\web\Controller - 确保请求头明确声明
Accept: application/json(fetch默认不加,得手动设) - 检查
response.formatters配置,确认'json' => ['class' => 'yii\web\JsonResponseFormatter']已启用且为默认 - 调试时用
curl -H "Accept: application/json" http://localhost/v1/users对比响应体,快速定位是服务端逻辑问题还是客户端头缺失
最常被忽略的是控制器类继承关系和行为过滤器顺序——写对了 behaviors() 里的 Cors 和 AuthMethod 位置,比写十个路由规则都管用。


















