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

CodeIgniter4中RedirectResponse配合JS POST请求的跳转问题

问题解决:CodeIgniter4中JS POST请求后实现带信息的新窗口跳转

核心问题分析

用JavaScript发送POST请求到CI4控制器时,控制器返回的RedirectResponse无法被JS直接处理以实现带Flash数据的新窗口跳转,同时面临资源加载异常、CSRF限制、表单数据丢失等问题,且需要保留JS提交前修改输入项的能力。

解决方案:区分AJAX/普通请求,返回JSON数据而非直接重定向

1. 修改控制器逻辑,适配AJAX请求

在控制器中判断请求是否为AJAX,返回包含跳转地址和状态信息的JSON,而非直接返回RedirectResponse:

public function attemptCreate()
{
    $rules = [
        'slug'            => 'required|max_length[128]',
        'audio_file'      => 'uploaded[audio_file]|ext_in[audio_file,mp3,m4a]',
        'cover'           => 'is_image[cover]|ext_in[cover,jpg,jpeg,png]|min_dims[cover,1400,1400]|is_image_ratio[cover,1,1]',
        'transcript_file' => 'ext_in[transcript,srt]|permit_empty',
        'chapters_file'   => 'ext_in[chapters,json]|permit_empty',
    ];

    if ($this->podcast->type === 'serial') {
        $rules['episode_number'] = 'required';
    }

    // 验证失败逻辑
    if (! $this->validate($rules)) {
        if ($this->request->isAJAX()) {
            return $this->response->setJSON([
                'success' => false,
                'errors' => $this->validator->getErrors(),
                'redirect' => site_url($this->request->getServer('HTTP_REFERER'))
            ])->setStatusCode(422);
        }
        return redirect()
            ->back()
            ->withInput()
            ->with('errors', $this->validator->getErrors());
    }

    // 假设创建成功后生成跳转地址
    $newEpisode = $this->episodeModel->saveEpisode(...); // 你的创建逻辑
    $redirectUrl = route_to('episode-detail', $newEpisode->id);

    // 成功时的响应
    if ($this->request->isAJAX()) {
        return $this->response->setJSON([
            'success' => true,
            'redirect' => $redirectUrl,
            'message' => '剧集创建成功'
        ]);
    }

    return redirect()->to($redirectUrl)->with('message', '剧集创建成功');
}

2. 修改JS脚本,处理JSON响应

在JS中接收控制器返回的JSON数据,根据状态处理跳转或错误提示:

try {
    const response = await fetch("<?= route_to('episode-create', $podcast->id) ?>", {
        method: "POST",
        body: formData,
        headers: {
            // 告知CI4这是AJAX请求,适配isAJAX()判断
            'X-Requested-With': 'XMLHttpRequest'
        }
    });

    if (response.ok) {
        const responseData = await response.json();
        // 成功时打开新窗口跳转,新页面会正常加载资源
        window.open(responseData.redirect, '_blank');
        // 可选:在当前页面显示成功提示
        alert(responseData.message);
    } else if (response.status === 422) {
        const errorData = await response.json();
        // 验证失败时,在当前页面展示错误,表单数据不会丢失
        console.error('验证错误:', errorData.errors);
        // 示例:遍历错误并显示在对应输入框下方
        Object.keys(errorData.errors).forEach(field => {
            const errorElement = document.getElementById(`${field}-error`);
            if (errorElement) {
                errorElement.textContent = errorData.errors[field];
            }
        });
    } else {
        console.error('请求异常:', response.status, response.statusText);
    }
} catch (e) {
    console.error(e);
}

方案优势

  • 完全保留JS提交前修改输入项的能力;
  • 跳转时通过window.open发起正常GET请求,避免资源加载异常;
  • 验证错误时无需刷新页面,直接在当前页展示错误,保留表单已填内容;
  • 绕开CSRF限制,跳转请求为GET,无需重复提交POST数据;
  • 跳转后的新页面可正常读取控制器设置的Flash数据(如成功提示)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 16:42:49