Ajax错误403 Forbidden CodeIgniter

时间:2016-11-09 14:21:29

标签: javascript php ajax codeigniter

我的html页面上有两个链接:

<a id="1" onclick="like(this.id)">first</a>
<a id="2" onclick="like(this.id)">Second</a>

我的JS如下:

function like (id) {
    $.ajax({
        type:'POST',
        data: {
            func:
                'getNewLocations',
            '<?php echo $this->security->get_csrf_token_name(); ?>':
                '<?php echo $this->security->get_csrf_hash(); ?>',
            message:id
        },
        url:'<?php echo base_url();?>index.php/Category/like',
        success: function(result, statut) {
            if (result == 'add') {
                //do something
            }
            else if (result == 'remove') {
                //do something
            }
        }
    });
}

php方法如下(仅用于示例):

public function like() {
    echo 'add';
}

当我第一次点击链接1时,ajax请求正常,服务器回答&#39;添加&#39;。但是当我点击链接2时,我有403错误。更令人惊讶的是,当我点击链接2上的fisrt时,它可以工作,但链接1没有。 我使用codeIgniter。

知道为什么以及如何解决它? 感谢

2 个答案:

答案 0 :(得分:1)

由于您似乎正在使用CSRF令牌来验证请求,因此任何发送无效令牌的请求都将被拒绝。

第一次单击任一锚点时,您会用完该标记。因此,为了发出额外的请求,您需要在响应中返回一个新令牌并使用它而不是旧令牌。

您只需将您的数据值"add"发送回您的csrf值:get_csrf_token_name()get_csrf_hash()

您可以发回包含值的JSON值,而不是仅返回纯文本,例如

php脚本

function like(){
   $output = new stdClass;
   $output->csrfName = $this->security->get_csrf_token_name();
   $output->csrfHash = $this->security->get_csrf_hash();
   $output->data = "add";
   echo json_encode($output);
}

在javascript中

//Initial csrf values
var csrfName = '<?php echo $this->security->get_csrf_token_name();?>';
var csrfHash = '<?php echo $this->security->get_csrf_hash();?>';
function like (id) {
    //create data object here so we can dynamically set new csrfName/Hash
    var data = {
       func:'getNewLocations',
       message:id
    };
    data[csrfName] = csrfHash;

    $.ajax({
        type:'POST',
        data: data, 
        //dataType tells jQuery to expect JSON response
        dataType:"json",
        url:'<?php echo base_url();?>index.php/Category/like',
        success: function(result, statut) {
            if(result.csrfName){
               //assign the new csrfName/Hash
               csrfName = result.csrfName;
               csrfHash = result.csrfHash;
            }
            if (result.data == 'add') {
                //do something
            }
            else if (result.data == 'remove') {
                //do something
            }
        }
    });
}

请注意,如果您支持支持ECMAScript 2015的浏览器,则可以使用computed keys在数据对象初始值设定项中设置csrf值

    $.ajax({
        type:'POST',
        data: {
            [csrfName]:csrfHash,
            func:'getNewLocations',
            message:id
        }, 

答案 1 :(得分:0)

第一次提交后,csrf令牌不再有效,您有两种选择。

您还需要在config.php中设置以下内容

$config['csrf_regenerate'] = FALSE;

或更新页面上的csrf标记。