我的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。
知道为什么以及如何解决它? 感谢
答案 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标记。