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

CodeIgniter启用CSRF后AJAX POST提交报403 Forbidden问题

解决CodeIgniter AJAX POST提交CSRF 403 Forbidden问题

根据你提供的配置和代码,咱们一步步排查并解决这个问题:

1. 确认表单选择器与CSRF令牌的归属

你提到控制台显示表单已包含CSRF令牌隐藏输入,但要先确保这个隐藏输入确实在你选中的#formData表单内部。form_open()默认不会给表单添加id="formData"属性,所以需要你在生成表单时显式指定:

<?php echo form_open('login/verify', ['id' => 'formData']); ?>

如果表单id不匹配,new FormData($(this)[0])就无法捕获CSRF令牌字段,自然会触发CSRF验证失败导致403。

2. 修正AJAX请求的URL路径

你的AJAX请求URL写的是'example.com.sg/login/verify',这种写法容易被浏览器解析为相对路径(比如当前页面是example.com.sg/login,会被解析为example.com.sg/login/example.com.sg/login/verify),导致请求到错误地址,触发验证失败。

建议用CodeIgniter的base_url()生成正确的绝对路径:

url: '<?php echo base_url('login/verify'); ?>',

如果你的JS代码是单独的外部文件,可以先在HTML页面中定义全局变量:

<script>const baseUrl = '<?php echo base_url(); ?>';</script>

再在JS中调用:

url: baseUrl + 'login/verify',

3. 确保AJAX请求携带Cookie(同域场景)

CodeIgniter的CSRF验证需要POST数据中的令牌和Cookie中的令牌匹配。虽然同域下AJAX默认会携带Cookie,但有些场景下可能被浏览器限制,你可以显式配置强制携带:

$.ajax({
    type: 'post',
    cache : false,
    processData: false,
    dataType: 'json',
    url: '<?php echo base_url('login/verify'); ?>',
    data: formData,
    // 添加这部分配置
    xhrFields: {
        withCredentials: true
    },
    success: function (res) {
        if(res.status == true){
            window.location.href = res.redirect;
        }
    },
    error: function(err){
        console.log(err.responseText)
    }
});

4. 验证请求中CSRF令牌的发送状态

打开浏览器开发者工具的Network标签,找到你的POST请求,查看Form Data部分是否包含csrf_token_name字段(对应你配置的$config['csrf_token_name']值)。如果没有,说明表单选择器错误或者令牌字段不在表单内,需要调整表单结构。

5. 排除其他干扰因素

  • 确认csrf_expire设置的7200秒(2小时)未过期,测试时可以临时设为更大的值(比如86400)验证;
  • 检查csrf_exclude_uris是否误添加了当前URI(你的配置是空数组,这部分没问题);
  • 确保服务器端没有其他安全插件/模块(比如ModSecurity)拦截了POST请求。

按照上面的步骤排查,应该能解决AJAX POST 403的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 14:47:48