yii中response默认不支持jsonp或纯文本异步响应,需显式设置format为format_json;csrf验证会导致ajax post 400错误,须传递x-csrf-token;jsonresponseformatter会包装布尔/null值,应使用asjson()精确控制输出;ajax中redirect()静默失败,应返回状态码和url由前端跳转。

Yii 中 yii\web\Response 默认不支持 JSONP 或纯文本异步响应
Yii 默认把 yii\web\Response 的 format 设为 Response::FORMAT_HTML,哪怕你用 $.ajax 或 fetch 发送请求,框架也不会自动切到 JSON 模式——除非你显式告诉它。常见现象是:前端收到 HTML 内容(比如整个错误页或登录跳转),而不是预期的 {"success":true}。
实操建议:
- 在控制器方法开头加
$this->response->format = Response::FORMAT_JSON;(需use yii\web\Response;) - 返回数组即可,Yii 会自动
json_encode并设Content-Type: application/json - 如果用
ActiveController或 REST 场景,优先走yii\rest\Controller,它默认处理Accept头并切换 format
CSRF 验证导致 Ajax POST 400 错误
Yii 默认开启 CSRF 验证,而原生 fetch 或 jQuery.ajax 不会自动携带 _csrf,结果触发 Bad Request (#400),错误信息里明确写着 "Missing required parameter: _csrf" 或类似提示。
实操建议:
- 前端从
<meta name="csrf-param" content="_csrf">和<meta name="csrf-token" content="...">中读取 token(Yii 自动注入) - POST 请求必须带
headers: {'X-CSRF-Token': token}(fetch)或headers: {'X-CSRF-Token': token}+dataType: 'json'(jQuery) - 后端可临时关闭验证(仅限调试):
public $enableCsrfValidation = false;,但上线前务必删掉
JsonResponseFormatter 对空数组/布尔值的输出不符合直觉
直接 return ['data' => []]; 没问题,但如果你写 return true; 或 return null;,Yii 会输出 {"success":true} 或空对象 {},而不是原始布尔或 null——这是 JsonResponseFormatter 的默认包装行为。
实操建议:
- 需要精确控制输出时,别依赖隐式返回,改用
return $this->asJson(['status' => 'ok']); - 要输出纯
null,得手动设置:$this->response->data = null; return $this->response; - 注意 PHP 版本差异:7.4+ 支持
json_encode(null, JSON_THROW_ON_ERROR),但 Yii 层已封装,绕过更稳妥
异步请求中重定向(redirect())会静默失败
Ajax 请求里调用 $this->redirect('/login'),前端收不到跳转,只看到一个 200 响应体含 HTML 登录页源码——因为浏览器不会执行响应里的 Location 头,JS 也没监听重定向逻辑。
实操建议:
- 绝对不要在 Ajax 动作里用
redirect() - 改用状态码 + 数据字段通知前端,例如:
return ['code' => 302, 'url' => '/login']; - 前端统一拦截
code === 302,再执行window.location.href = data.url - 如果用了
yii\filters\AccessControl,它的默认拒绝行为也是跳转,记得覆盖denyCallback返回 JSON
真正麻烦的是跨域、多层中间件和自定义 response formatter 的组合场景——那些地方 token、header、format 的优先级容易打架,得一层层看 beforeSend 和 afterSend 的实际输出。










