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

Yii框架功能测试中\Yii::$app->request->isAjax不生效问题

解决Yii功能测试中AJAX请求头校验的问题

我刚接触功能测试时也踩过类似的坑,别慌,咱们一步步把这个问题搞定!

首先得理清核心矛盾:你的update-ajax控制器靠\Yii::$app->request->isAjax做校验,而这个校验的核心是判断请求是否携带X-Requested-With: XMLHttpRequest头,但Codeception的**功能测试(Functional Tests)**里,$I->haveHttpHeader确实不生效——因为这个方法是给验收测试(模拟真实浏览器请求场景)设计的,功能测试直接调用Yii内核,不走完整HTTP请求流程,所以得换个思路设置请求头。

下面给你几个实用的解决方案:

方案1:在测试方法内手动设置Yii请求头

在你的WorkflowCest测试方法里,发送请求前直接给Yii的request组件添加目标请求头:

public function testUpdateAjax(FunctionalTester $I)
{
    // 先设置AJAX请求头
    \Yii::$app->request->headers->set('X-Requested-With', 'XMLHttpRequest');
    
    // 再执行请求操作,比如POST请求
    $I->sendPost('/your/update-ajax/route', [
        // 这里填写你的请求参数
    ]);
    
    // 后续断言逻辑
    $I->seeResponseCodeIs(200);
    // ...其他业务相关断言
}

方案2:全局设置请求头(所有测试方法通用)

如果多个测试用例都需要AJAX请求头,可以在Cest的_before方法里统一配置,避免重复代码:

public function _before(FunctionalTester $I)
{
    // 每次测试执行前自动添加AJAX请求头
    \Yii::$app->request->headers->set('X-Requested-With', 'XMLHttpRequest');
}

方案3:用sendRequest方法直接传递请求头

Codeception功能测试里的sendRequest方法支持直接传入headers参数,这种方式更灵活,适合只在个别请求需要AJAX头的场景:

public function testUpdateAjax(FunctionalTester $I)
{
    $I->sendRequest(
        'POST', 
        '/your/update-ajax/route', 
        [/* 请求参数 */], 
        [
            'X-Requested-With' => 'XMLHttpRequest'
        ]
    );
    
    // 执行断言逻辑
}

调试小技巧

可以在update-ajax控制器里临时加一段调试代码,确认请求头是否正确带上:

public function actionUpdateAjax()
{
    // 临时调试,查看请求头状态
    var_dump(\Yii::$app->request->headers->get('X-Requested-With'));
    die;
    
    // 原有业务逻辑
    if (\Yii::$app->request->isAjax) {
        // ...你的业务代码
    }
}

这样就能直观确认请求头是否设置成功,快速排除配置问题!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:29:22