Yii 在 ajax 调用中使用 PageCaching 时不起作用

Yii When using PageCaching in ajax call not working

我试图在 Yii2 高级项目中实现页面缓存,一切看起来都非常酷。突然我遇到了一个奇怪的问题。

案例:在网站的主页上有一些动态数据,如显示来自数据库的记录,当前用户的信息,如姓名(如果用户已登录)和一些静态内容。此外,搜索输入字段使用 AJAX 调用获取结果。

为了加快页面加载速度,我实现了 Yii2 提供的 PageCaching。一切都很好。但我遇到的一个问题是,在用户登录后,ajax 调用不起作用并给出错误:

Bad Request (#400): Unable to verify your data submission.

直到缓存在设置的持续时间后刷新或者我禁用了缓存,我才收到此错误。

此问题与 cookie/session 或其他问题有关吗?如何解决?

400 Bad Request 是因为 csrf-token 没有被发送,当你使用 POST 提交页面时,需要防止 Yii 跨站攻击的请求或 ajax 请求,如果您创建 ActiveForm 则它会自动创建一个带有令牌值的输入。

您没有添加用于 ajax 调用的代码,因此不清楚您是仅将其用于一个字段还是整个表单,因此我只建议相关部分。

您需要发送 csrf-token,您可以通过 javascript 使用 yii.js 并调用这 2 个方法

来获取它
  • yii.getCsrfParam()获取token的参数名
  • yii.getCsrfToken()获取csrf-token的token或实际值

csrfParam 名称在 frontend/config.phpconfig/web.php 中配置,具体取决于您在 request 组件下使用的应用程序(高级/基本),如下所示

'components'=>[
    ......
    ......
    'request' => [
        'csrfParam' => '_csrf-frontend',
    ],
    ......
    ......
]

所以你需要做的是将请求方法从 POST 更改为 GET 并通过查询字符串发送数据,或者使用以下方式发送 POST 请求。

Note: You should change the URL and add the csrf data into your existing data that you are sending with the request

let data={};
data[yii.getCsrfParam()]=yii.getCsrfToken();
$.ajax(
    {
        method:"POST",
        url:"/site/test",
        data:data,
        success:function(data) {
            console.log(data);
        },
        error:function(jqXHR,textStatus,errorThrown) {
            console.log(jqXHR,textStatus,errorThrown);
        }
    }
);

如果您在 SiteController 中使用以下代码执行 test 操作,那么上面的 ajax 调用应该会向您显示控制台中的 $_POST 数组csrf 参数和令牌值为 key=>value.

public function actionTest()
{
    print_r($_POST);
}