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

Codeigniter CSRF安全下AngularJS 1.x的$http.post()报500错误求助

解决CodeIgniter CSRF下AngularJS 1.x $http.post 500错误的方案

看起来你遇到的问题是CodeIgniter的CSRF验证在AJAX请求时没通过,导致500错误。普通表单能正常工作是因为CodeIgniter会自动为表单生成隐藏的CSRF令牌字段,而AngularJS的AJAX请求需要我们手动处理令牌传递,同时还要注意请求格式和后端的解析逻辑。

下面分步骤帮你解决:

第一步:确认CodeIgniter的CSRF配置

先打开application/config/config.php,找到这几个关键配置项,记好它们的值:

$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_test_name'; // POST请求里需要携带的参数名
$config['csrf_cookie_name'] = 'csrf_cookie_name'; // 存储令牌的cookie名称

你的Angular代码里用的csrf_crypt大概率和csrf_token_name不一致,这是常见的错误点。

方案一:用表单编码格式提交(和普通表单一致)

这个方案最稳妥,因为和普通表单的请求格式完全相同,CodeIgniter能直接解析验证。

修改你的Angular代码:

  1. 注入$httpParamSerializerJQLike(用来序列化表单数据)
  2. 正确获取CSRF令牌的名称和值
  3. 调整$http请求的配置
var angCntrl = angular.module('stepsReg',['ngMaterial', 'ngMessages', 'material.svgAssetsCache','mdPickers','naif.base64','ngFileUpload','uiCropper','ngCookies'])
// 注入$httpParamSerializerJQLike用于表单数据序列化
angCntrl.controller('DemoCtrl', function($scope,$window, $cookies,$http,$httpParamSerializerJQLike,$mdpDatePicker,$mdpTimePicker,$timeout,$q,$mdDialog,$filter,Upload) {
 // 替换成你config里的csrf_token_name和csrf_cookie_name
 var csrfTokenName = 'csrf_test_name';
 var csrfTokenValue = $cookies.get('csrf_cookie_name');

 $scope.insertid = '';
 $scope.outletid = '';
 $scope.currentid = currentid;

 $scope.stepOneNext = function() {
  var insertid = $('#insertid').val();
  var profileId = $('.current_id').val();
  var pCategory = $('#parentCat').val();
  var name = $('#name').val();
  var email = $('#email').val();

  // 构造请求数据,把CSRF令牌放在最前面
  var postData = {};
  postData[csrfTokenName] = csrfTokenValue;
  postData.insertid = insertid;
  postData.profileId = profileId;
  postData.pCategory = pCategory;
  postData.name = name;
  postData.email = email;

  $http({
   method: 'post',
   url: base_url+'customer/steponeRegistion',
   // 序列化数据成表单格式
   data: $httpParamSerializerJQLike(postData),
   // 设置正确的Content-Type
   headers: {'Content-Type': 'application/x-www-form-urlencoded'}
  }).then(function (response) {
   alert(response.data);
   $scope.insertid = response.data;
  }).catch(function(error) {
   // 增加错误捕获,方便调试
   console.error('请求出错:', error);
   alert('请求失败,请查看控制台日志');
  });
 }
});

方案二:让CodeIgniter支持JSON格式的CSRF验证

如果你坚持用JSON格式提交数据,需要修改CodeIgniter的Security类,让它能从JSON请求体里读取CSRF令牌。

  1. 在application/core目录下创建MY_Security.php文件,内容如下:
<?php
class MY_Security extends CI_Security {
    protected function csrf_verify() {
        // 先执行默认的CSRF验证(处理表单编码的请求)
        if (parent::csrf_verify()) {
            return TRUE;
        }
        // 如果默认验证失败,尝试解析JSON请求体
        $rawInput = file_get_contents('php://input');
        $inputData = json_decode($rawInput, TRUE);
        
        // 检查JSON里是否包含正确的CSRF令牌
        if (isset($inputData[$this->_csrf_token_name]) && $this->csrf_validate_token($inputData[$this->_csrf_token_name])) {
            $this->_csrf_set_hash(); // 更新CSRF令牌
            return TRUE;
        }
        // 验证失败,返回错误
        $this->csrf_show_error();
        return FALSE;
    }
}
  1. 然后修改你的Angular代码,确保CSRF令牌的参数名和CodeIgniter的csrf_token_name一致,并且正确设置请求头:
var angCntrl = angular.module('stepsReg',['ngMaterial', 'ngMessages', 'material.svgAssetsCache','mdPickers','naif.base64','ngFileUpload','uiCropper','ngCookies'])
angCntrl.controller('DemoCtrl', function($scope,$window, $cookies,$http,$mdpDatePicker,$mdpTimePicker,$timeout,$q,$mdDialog,$filter,Upload) {
 var csrfTokenName = 'csrf_test_name'; // 替换成你的config值
 var csrfTokenValue = $cookies.get('csrf_cookie_name');

 $scope.insertid = '';
 $scope.outletid = '';
 $scope.currentid = currentid;

 $scope.stepOneNext = function() {
  var insertid = $('#insertid').val();
  var profileId = $('.current_id').val();
  var pCategory = $('#parentCat').val();
  var name = $('#name').val();
  var email = $('#email').val();

  $http({
   method: 'post',
   url: base_url+'customer/steponeRegistion',
   data:{
    [csrfTokenName]: csrfTokenValue,
    "insertid":insertid,
    "profileId":profileId,
    "pCategory":pCategory,
    "name":name,
    "email":email
   },
   // 正确设置JSON请求头,之前的config写法错误
   headers: {'Content-Type': 'application/json'}
  }).then(function (response) {
   alert(response.data);
   $scope.insertid = response.data;
  }).catch(function(error) {
   console.error('请求出错:', error);
  });
 }
});

额外调试建议

  • 打开浏览器开发者工具(F12),查看Network标签里的请求,检查Request Headers和Form Data/Payload里是否包含正确的CSRF令牌。
  • 查看CodeIgniter的日志文件(application/logs/目录下),500错误通常会有详细的PHP错误信息,能帮你快速定位问题。
  • 确保base_url没有跨域问题,如果是跨域请求,还需要配置CORS并允许携带cookie。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:04:37