現在、ドットインストールの『PHPでTodo管理アプリを作ろう』を参考に、CodeIgniter3で簡単なTodoアプリを作成中です。
config.phpで$config['csrf_protectin] = TRUE
および$config['csrf_regenerate'] = TRUE
としたうえで、以下のようなコードをviewに書きました(一部抜粋)。
lang
1<scritp> 2 $(function() { 3 // チェックボックスをクリックして、Todoの完了/未完了を切り替える(取り消し線の表示/非表示を切り替える) 4 $('#todos').on('click', '.update_todo', function() { 5 var id = $(this).parents('li').data('id'); 6 $.ajax({ 7 type: 'POST', 8 url: '<?php echo site_url('todos/update'); ?>', 9 data: { 10 '<?php $this->security->get_csrf_token_name(); ?>': '<?php $this->security->get_csrf_hash(); ?>', 11 id: id 12 }, 13 dataType: 'json' 14 }) 15 .done(function(result) { 16 if (result === '1') { 17 $('#todo_' + id).find('.todo_title').addClass('done'); 18 } else { 19 $('#todo_' + id).find().removeClass('done'); 20 } 21 }); 22 });
上記に加えて、追加および削除の機能も実装済みです。
なお、Todoを追加するための入力フォームにはform_open()
を使用しています。
CSRFプロテクションが無効であれば、すべての機能が正常に動作します。
しかし、CSRFプロテクションを有効化すると、ページ読み込み後の最初の1回しかajaxが動いてくれません。
ちなみに$config['csrf_regenerate']
をFALSEに設定してみたところ、CSRFプロテクションが無効であるときと同様に、そのような問題は発生しませんでした。
あくまで$config['csrf_protectin] = TRUE
および$config['csrf_regenerate'] = TRUE
としたうえで、ajaxを利用したいのですが、どなたか解決策をお教えいただけないでしょうか。
どうぞよろしくお願いいたします。
追記
ここを参考に(というか丸写しして)、次のように書きました。
lang
1<script> 2 csrf_token_name = '<?php echo $this->security->get_csrf_token_name(); ?>'; // 追加 3 csrf_cookie_name = '<?php echo $this->config->item('csrf_cookie_name'); ?>'; // 追加 4 $(function() { 5 'use strict'; 6 7 // 追加 -------------------------------------------------------- 8 var object = {}; 9 object[csrf_token_name] = $.cookie(csrf_cookie_name); 10 $.ajaxSetup({ 11 data: object 12 }); 13 $(document).ajaxComplete(function() { 14 object[csrf_token_name] = $.cookie(csrf_cookie_name); 15 $.ajaxSetup({ 16 data: object 17 }); 18 }); 19 // ------------------------------------------------------------- 20 21 // update 22 $('#todos').on('click', '.update_todo', function() { 23 var id = $(this).parents('li').data('id'); 24 $.ajax({ 25 type: 'POST', 26 url: '<?php echo site_url('todos/update'); ?>', 27 data: { 28 id: id 29 }, 30 dataType: 'json' 31 }) 32 .done(function(result) { 33 if (result === '1') { 34 $('#todo_' + id).find('.todo_title').addClass('done'); 35 } else { 36 $('#todo_' + id).find('.todo_title').removeClass('done'); 37 } 38 }); 39 }); 40 41 // create 42 $('#new_todo_form').on('submit', function() { 43 var title = $('#new_todo').val(); 44 $.ajax({ 45 type: 'POST', 46 url: '<?php echo site_url('todos/create'); ?>', 47 data: { 48 title: title 49 }, 50 dataType: 'json' 51 }) 52 .done(function(result) { 53 var $li = $('#todo_template').clone(); 54 $li 55 .attr('id', 'todo_' + result.id) 56 .data('id', result.id) 57 .find('.todo_title').text(title); 58 $('#todos').prepend($li.fadeIn()); 59 $('#new_todo').val('').focus(); 60 }); 61 }) 62 63 // delete 64 $('#todos').on('click', '.delete_todo', function() { 65 var id = $(this).parents('li').data('id'); 66 if (confirm('are you sure?')) { 67 $.ajax({ 68 type: 'POST', 69 url: '<?php echo site_url('todos/delete'); ?>', 70 data: { 71 id: id 72 } 73 }) 74 .done(function() { 75 $('#todo_' + id).fadeOut(400); 76 }); 77 } 78 }); 79 }); 80</script>
こうすると、$config['csrf_regenerate'] = TRUE
の状態でもupdateとdeleteのajaxが正常に動きます。
ただ、createを実行すると、"The action you have requested is not allowed."のエラーページに飛ばされてしまいます(Todoの作成自体はできているようです)。
原因をお教えいただければ幸いです。
どうぞよろしくお願いいたします。
追記
上記のコードは、createのところでfalseを返し忘れています。
試してはいませんが、done()メソッドの後にreturn false;
を挿入することで、すべてのajaxが正常に動作するかもしれません。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/09/02 06:59
2018/09/02 16:47