You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yii2框架jQuery POST请求返回400 Bad Request错误如何解决

Yii2 多语言切换POST请求400错误修复方案

核心原因

Yii2框架默认开启全局POST请求的CSRF跨站请求伪造校验,你的前端AJAX请求没有携带框架要求的CSRF校验令牌,会被框架直接拦截返回400状态码,这是Yii2开发中POST请求报400的最高频原因。同时你的前后端代码还存在几处语法和逻辑bug,一并修复即可正常运行。

具体修复步骤

  • 修正前端jQuery代码
    你原来的JS代码存在三个问题:最后多了一个多余的闭合大括号会触发语法错误、用全局选择器拿语言值永远只会取第一个语言选项的id、多余的JSON.stringify会把语言值包成多余的带引号字符串、缺少CSRF校验参数。替换为如下代码即可:
$(document).on('click','.language',function() {
    // 取当前点击元素的id作为语言值,不需要JSON序列化
    var lang = $(this).attr('id');
    console.log("当前选中语言:" + lang);

    $.post('language', {
        'lang': lang,
        // 携带Yii2要求的CSRF校验参数,方法由Yii框架自带的前端资源提供
        [yii.getCsrfParam()]: yii.getCsrfToken()
    }, function() {
        location.reload();
    });
});
  • 修正后端控制器代码
    你原来的PHP代码里误用了JS的console.log()语法,会触发PHP语法错误,同时缺少语言值合法性校验、cookie过期时间设置,也没有给前端返回正常响应。替换为如下代码:
public function actionLanguage()
{
    if (Yii::$app->request->isPost && $lang = Yii::$app->request->post('lang')) {
        // 配置你项目实际支持的语言白名单,避免传入非法值
        $allowedLanguages = ['zh-CN', 'en-US'];
        if (in_array($lang, $allowedLanguages)) {
            Yii::$app->language = $lang;
            $cookie = new yii\web\Cookie([
                'name' => 'lang',
                'value' => $lang,
                'expire' => time() + 86400 * 365, // cookie有效期1年,避免关闭浏览器就失效
            ]);
            Yii::$app->response->cookies->add($cookie);
        }
    }
    // 处理完成后跳回来源页,比前端强制reload兼容性更好
    return $this->redirect(Yii::$app->request->referrer);
}

安全提示:关闭CSRF校验会让接口暴露在跨站请求伪造风险下,优先使用携带CSRF参数的方案。

  • (不推荐)可选方案:单独关闭该接口的CSRF校验
    如果你不想在前端传CSRF参数,可以在对应控制器里把这个接口加入CSRF校验白名单:
public function beforeAction($action)
{
    if ($action->id === 'language') {
        $this->enableCsrfValidation = false;
    }
    return parent::beforeAction($action);
}

内容的提问来源于stack exchange,提问作者Paul Stokvinsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 03:06:38