JQueryの変更イベントでサーバーに画像をアップロードしたいのですが、codeigniter csrfを使用すると、画像を一度だけアップロードできます。複数のリクエストに対してajaxを使用して画像をアップロードするにはどうすればよいですか?これを設定するときは注意してください
config['csrf_protection'] = FALSE;
その後、複数のリクエストjQuery onchangeイベントを送信できますが、csrf_protectionがfalseになるとcsrfの利点はないと思います。したがって、質問は、csrf_protectionが有効なときにajaxを使用して複数のリクエストを送信する方法です。私のjqueryコードは次のとおりです
$("#avatar").change(function(){
var link = $("#avatar").val();
$.ajax({
url : "<?php echo base_url('main/test'); ?>",
type: 'post',
data: {'<?php echo $this->security->get_csrf_token_name(); ?>':'<?php echo $this->security->get_csrf_hash(); ?>',"id":"hello","link":link},
success : function(data)
{
alert(data);
}
});
});
私の意見では、リクエストごとにcsrfトークンを再作成する必要があります
このコード例を試してください...
Js機能について
var csrfName = '<?php echo $this->security->get_csrf_token_name(); ?>',
csrfHash = '<?php echo $this->security->get_csrf_hash(); ?>';
("#avatar").change(function(){
var link = $("#avatar").val();
var dataJson = { [csrfName]: csrfHash, id: "hello", link: link };
$.ajax({
url : "<?php echo base_url('main/test'); ?>",
type: 'post',
data: dataJson,
success : function(data)
{
csrfName = data.csrfName;
csrfHash = data.csrfHash;
alert(data.message);
}
});
});
そしてコントローラー用
public function test() {
$config['upload_path'] = './uploads/';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = 500;
$config['max_width'] = 260;
$config['max_height'] = 260;
$reponse = array(
'csrfName' => $this->security->get_csrf_token_name(),
'csrfHash' => $this->security->get_csrf_hash()
)
$this->load->library('upload', $config);
if (!$this->upload->do_upload('link')) {
$reponse['message'] = "error";
}
else {
$data = array('upload_data' => $this->upload->data());
$image_name = $data['upload_data']['file_name'];
$reponse['message'] = $image_name;
}
echo json_encode($reponse);
}
私に知らせて、幸運を
注:誰かが質問にさらにデータを投稿するように頼んだら、コメントや回答として投稿しないでください。質問自体を編集して、内容を追加する方が良いです
これはconfig.phpで設定できます
$config['csrf_regenerate'] = FALSE;
したがって、csrf保護はすべてのセッション時間中有効であり、問題を解決します。 $config['csrf_regenerate'] = true;
を設定すると、CIはリクエストごとに新しいcsrfトークンを生成するため、古いcsrfトークンは新しく生成されたcsrfトークンと一致しません
あなたがする必要があるのは、AJAXレスポンスでCSRFトークンをリロードすることです。それはとても簡単です!
$config['csrf_regenerate'] = TRUE;
自動生成をtrueにすると、より安全になります。同様の場合、最初の要求でcsrfが期限切れになる場合。私が実装したもの
$(document).ajaxComplete(function (event, xhr, settings) {
let response = xhr.responseText,
let obj = JSON.parse(response),
let csrfData = obj.csrf;
document.querySelector('input[name="' + csrfData.name + '"]').value = csrfData.hash;
}); //Also here you can update any other non input element
すべてのajax応答で、最新のcsrfデータが現在のcsrfデータに置き換えられるcsrfデータを渡します
リクエストからのサンプル応答
{
csrf : {
name : 'csrf_name',
hash : 'qw76sd7s6f78sdfs8dfs9df8cx9'
}
}
すべてのajaxリクエストでcsrfトークンを更新します。また、マルチタブ環境で作業している場合は、この方法を選択しないでください
これをすべてのページにロードされるjsファイルに追加します(これをjquery.jsの最後に配置します)
$.ajaxSetup({
beforeSend:function(jqXHR, Obj){
var value = "; " + document.cookie;
var parts = value.split("; csrf_cookie_name=");
if(parts.length == 2)
Obj.data += '&csrf_token='+parts.pop().split(";").shift();
}
});
(すべてのajaxリクエストでは、送信する空のデータを保持できないことに注意してください)
config.phpで定義されている上部の「csrf_cookie_name」
$config['csrf_cookie_name'] = 'csrf_cookie_name';
リクエストを行うたびに、csrf_token
は[〜#〜] ci [〜#〜]によって更新されます。 [〜#〜] csrf [〜#〜]が一度しか機能しないのはそのためです。そのため、リクエストを行うたびに、csrf_tokenも更新する必要があります。これを行うことでこの問題を解決します。
Conroller:このコードを使用して更新されたcsrfを取得します。
public function update_csrf()
{
$data['csrf_hash'] = $this->security->get_csrf_hash();
echo json_encode($data);
}
[〜#〜] ajax [〜#〜]:yourの古い値を置き換えるcsrf = name="csrf_token_name"
var jqXHR = $.ajax({
url: $(this).attr('action'),
type: 'POST',
data: $(this).serialize(),
dataType: 'json',
})
jqXHR.done(function(response) {
$('input[name=csrf_token_name]').val(response.csrf_hash); //update the csrf to the form
})
jqXHR.fail(function(jqXHR, textStatus, errorThrown) {
console.log(jqXHR);
console.log(textStatus);
console.log(errorThrown);
});
重要 !:
dataType: 'json'
を使用
したがって、リクエストが成功するたびに、csrf_token
も更新され、403(Forbidden)errorから解放されます。
私のコードのように試してください。その動作私のアプリケーション
あなたのビューファイル
$token_name = $this->security->get_csrf_token_name();
$token_hash = $this->security->get_csrf_hash();
<input type="text" id="search-text" name="parent_name" placeholder="Search" value="" >
<input type="hidden" id="csrf" name="<?php echo $token_name; ?>" value="<?php echo $token_hash; ?>" />
以下のようなjquery postメソッドを設定した後
// Get Keyup
jQuery( "#search-text").keyup(function() {
// Get Data
var val = jQuery("#search-text").val();
var hashValue = jQuery('#csrf').val();
// Get jquery post for ajax task
jQuery.post(
'<?php echo $base_controler; ?>',
{val:val,'<?php echo $this->security->get_csrf_token_name(); ?>':hashValue},
function(data)
{
// Get return data to decode
var obj = jQuery.parseJSON(data);
// Get csrf new hash value
var new_hash = obj.csrfHash;
// Set csrf new hash value update
jQuery('#csrf').val(new_hash);
}
);
});
以下のようにコントローラーを設定してください
$reponse = array(
'csrfName' => $this->security->get_csrf_token_name(),
'csrfHash' => $this->security->get_csrf_hash()
);
echo json_encode($reponse);
上記のすべてのコードは、リクエストごとにcsrfトークンを再作成します。