私はajax経由でデータベースからデータを削除しようとしています。
HTML:
@foreach($a as $lis)
//some code
<a href="#" class="delteadd" id="{{$lis['id']}}">Delete</a>
//click action perform on this link
@endforeach
私のajaxコード:
$('body').on('click', '.delteadd', function (e) {
e.preventDefault();
//alert('am i here');
if (confirm('Are you sure you want to Delete Ad ?')) {
var id = $(this).attr('id');
$.ajax({
method: "POST",
url: "{{url()}}/delteadd",
}).done(function( msg ) {
if(msg.error == 0){
//$('.sucess-status-update').html(msg.message);
alert(msg.message);
}else{
alert(msg.message);
//$('.error-favourite-message').html(msg.message);
}
});
} else {
return false;
}
});
これは、データベースからデータを取得するためのクエリです...
$a = Test::with('hitsCount')->where('userid', $id)->get()->toArray();
しかし、削除されていないリンクデータを削除し、csrf_tokenの不一致を表示すると...
Ajaxリクエストにdataを追加する必要があります。うまくいくことを願っています。
data: {
"_token": "{{ csrf_token() }}",
"id": id
}
この問題「X-CSRF-TOKEN」を解決する最善の方法は、メインレイアウトに次のコードを追加し、通常どおりajax呼び出しを行うことです。
ヘッダー内
<meta name="csrf-token" content="{{ csrf_token() }}" />
スクリプト内
<script type="text/javascript">
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
</script>
フォームにトークンを入れて、このトークンをIDで取得する方が良いと思います
<input type="hidden" name="_token" id="token" value="{{ csrf_token() }}">
そして、JQUery:
var data = {
"_token": $('#token').val()
};
このように、JSをブレードファイルに含める必要はありません。
Ajax呼び出しにheaders:
を追加しました:
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
ビューで:
<div id = 'msg'>
This message will be replaced using Ajax. Click the button to replace the message.
</div>
{{ Form::submit('Change', array('id' => 'ajax')) }}
ajax関数:
<script>
$(document).ready(function() {
$(document).on('click', '#ajax', function () {
$.ajax({
type:'POST',
url:'/ajax',
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
success:function(data){
$("#msg").html(data.msg);
}
});
});
});
</script>
コントローラー内:
public function call(){
$msg = "This is a simple message.";
return response()->json(array('msg'=> $msg), 200);
}
routes.phpで
Route::post('ajax', 'AjaxController@call');
テンプレートファイルを使用している場合は、meta
タグを含むヘッドsection
(または任意の名前)にmeta
タグを配置できます。
@section('head')
<meta name="csrf_token" content="{{ csrf_token() }}" />
@endsection
次に、headers
属性をajax
に追加する必要があります(私の例では、サーバー側の処理でdatatable
を使用しています:
"headers": {'X-CSRF-TOKEN': $('meta[name="csrf_token"]').attr('content')}
完全なdatatable
ajaxの例は次のとおりです。
$('#datatable_users').DataTable({
"responsive": true,
"serverSide": true,
"processing": true,
"paging": true,
"searching": { "regex": true },
"lengthMenu": [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"] ],
"pageLength": 10,
"ajax": {
"type": "POST",
"headers": {'X-CSRF-TOKEN': $('meta[name="csrf_token"]').attr('content')},
"url": "/getUsers",
"dataType": "json",
"contentType": 'application/json; charset=utf-8',
"data": function (data) {
console.log(data);
},
"complete": function(response) {
console.log(response);
}
}
});
これを実行した後、ajax
要求に対して200 status
を取得する必要があります。
jQueryを使用してAJAX投稿を送信する場合、次のコードをすべてのビューに追加します。
$( document ).on( 'ajaxSend', addLaravelCSRF );
function addLaravelCSRF( event, jqxhr, settings ) {
jqxhr.setRequestHeader( 'X-XSRF-TOKEN', getCookie( 'XSRF-TOKEN' ) );
}
function getCookie(name) {
function escape(s) { return s.replace(/([.*+?\^${}()|\[\]\/\\])/g, '\\$1'); };
var match = document.cookie.match(RegExp('(?:^|;\\s*)' + escape(name) + '=([^;]*)'));
return match ? match[1] : null;
}
LaravelはすべてのリクエストにXSRF Cookieを追加し、送信する直前にすべてのAJAXリクエストに自動的に追加します。
同じことを行う別の関数またはjQueryプラグインがある場合は、getCookie関数を置き換えることができます。
便宜上設定されたX-XSRF-TOKEN Cookieがあることを知ってください。 Angularなどのフレームワークはデフォルトで設定します。これをドキュメントで確認してください https://laravel.com/docs/5.7/csrf#csrf-x-xsrf-token 使用することができます。
最善の方法は、Cookieが無効になっている場合にメタを使用することです。
var xsrfToken = decodeURIComponent(readCookie('XSRF-TOKEN'));
if (xsrfToken) {
$.ajaxSetup({
headers: {
'X-XSRF-TOKEN': xsrfToken
}
});
} else console.error('....');
ここで推奨されるメタの方法(フィールドはどのようにでも配置できますが、メタは静かですNice):
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
decodeURIComponent()
の使用に注意してください。これは、Cookieの保存に使用されるuri形式からのデコードです。 [それ以外の場合、laravelで無効なペイロードの例外が発生します]。
ここでチェックするドキュメントのcsrf cookieに関するセクション: https://laravel.com/docs/5.7/csrf#csrf-x-csrf-token
また、ここでlaravel(bootstrap.js)がデフォルトでaxiosに設定する方法:
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
resources/js/bootstrap.js
を確認してください。
そして、ここでクッキー関数を読んでください:
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
実際にこのエラーが発生し、解決策が見つかりませんでした。私は実際にajaxリクエストを行わないことになりました。この問題の原因がサーバー上のサブドメインであるためかどうかはわかりません。これが私のjqueryです。
$('#deleteMeal').click(function(event) {
var theId = $(event.currentTarget).attr("data-mealId");
$(function() {
$( "#filler" ).dialog({
resizable: false,
height:140,
modal: true,
buttons: {
"Are you sure you want to delete this Meal? Doing so will also delete this meal from other users Saved Meals.": function() {
$('#deleteMealLink').click();
// jQuery.ajax({
// url : 'http://www.mealog.com/mealtrist/meals/delete/' + theId,
// type : 'POST',
// success : function( response ) {
// $("#container").replaceWith("<h1 style='color:red'>Your Meal Has Been Deleted</h1>");
// }
// });
// similar behavior as clicking on a link
window.location.href = 'http://www.mealog.com/mealtrist/meals/delete/' + theId;
$( this ).dialog( "close" );
},
Cancel: function() {
$( this ).dialog( "close" );
}
}
});
});
});
したがって、実際には、ポストリクエストを行うのではなく、APIにアクセスするようにアンカーを設定します。これは、ほとんどのアプリケーションが行うことです。
<p><a href="http://<?php echo $domain; ?>/mealtrist/meals/delete/{{ $meal->id }}" id="deleteMealLink" data-mealId="{{$meal->id}}" ></a></p>
CSRF保護 ミドルウェアがリクエストを検証できるように、非表示のCSRF(クロスサイトリクエストフォージェリ)トークンフィールドをフォームに含める必要があります。
Laravelは、アプリケーションによって管理されるアクティブなユーザーセッションごとにCSRF「トークン」を自動的に生成します。このトークンは、認証されたユーザーが実際にアプリケーションへのリクエストを処理していることを確認するために使用されます。
そのため、ajaxリクエストを行う場合、csrf tokenをdataパラメーター経由で渡す必要があります。これがサンプルコードです。
var request = $.ajax({
url : "http://localhost/some/action",
method:"post",
data : {"_token":"{{ csrf_token() }}"} //pass the CSRF_TOKEN()
});