php ajax POST请求的Laravel csrf令牌不匹配
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32738763/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel csrf token mismatch for ajax POST Request
提问by Ashish Singh
I am trying to delete data from database via ajax.
我正在尝试通过ajax从数据库中删除数据。
HTML:
HTML:
@foreach($a as $lis)
//some code
<a href="#" class="delteadd" id="{{$lis['id']}}">Delete</a>
//click action perform on this link
@endforeach
My ajax code:
我的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;
}
});
This is my query to fetch data from database...
这是我从数据库中获取数据的查询...
$a = Test::with('hitsCount')->where('userid', $id)->get()->toArray();
But when i click on Delete link data not deleted and show csrf_token mismatch...
但是当我点击删除链接数据未删除并显示 csrf_token 不匹配时...
回答by zarpio
The best way to solve this problem "X-CSRF-TOKEN" is to add the following code to your main layout, and continue making your ajax calls normally:
解决这个问题“X-CSRF-TOKEN”的最好方法是在你的主布局中添加以下代码,并继续正常进行ajax调用:
In header
在标题中
<meta name="csrf-token" content="{{ csrf_token() }}" />
In script
在脚本中
<script type="text/javascript">
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
</script>
回答by Deepak saini
You have to add datain your ajax request. I hope so it will be work.
您必须在 ajax 请求中添加数据。我希望它会起作用。
data: {
"_token": "{{ csrf_token() }}",
"id": id
}
回答by cmnardi
I think is better put the token in the form, and get this token by id
我认为最好将令牌放在表单中,并通过 id 获取此令牌
<input type="hidden" name="_token" id="token" value="{{ csrf_token() }}">
And the JQUery :
和 JQUEry :
var data = {
"_token": $('#token').val()
};
this way, your JS don't need to be in your blade files.
这样,您的 JS 不需要在您的刀片文件中。
回答by lewis4u
I just added headers:
in ajax call:
我刚刚headers:
在ajax调用中添加:
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
in view:
鉴于:
<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 function:
阿贾克斯功能:
<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>
in controller:
在控制器中:
public function call(){
$msg = "This is a simple message.";
return response()->json(array('msg'=> $msg), 200);
}
in routes.php
在routes.php
Route::post('ajax', 'AjaxController@call');
回答by Brane
If you are using template files, than you can put your meta
tag in the head section
(or whatever you name it) which contain your meta
tags.
如果您使用的是模板文件,那么您可以将您的meta
标签放在包含您的标签的头部section
(或您命名的任何名称)中meta
。
@section('head')
<meta name="csrf_token" content="{{ csrf_token() }}" />
@endsection
Next thing, you need to put the headers
attribute to your ajax
(in my example, I am using datatable
with server-side processing:
接下来,您需要将headers
属性放入您的ajax
(在我的示例中,我使用datatable
服务器端处理:
"headers": {'X-CSRF-TOKEN': $('meta[name="csrf_token"]').attr('content')}
Here is the full datatable
ajax example:
这是完整的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);
}
}
});
After doing this, you should get 200 status
for your ajax
request.
这样做之后,您应该得到200 status
您的ajax
请求。
回答by Mohamed Allal
Know that there is an X-XSRF-TOKEN cookie that is set for convenience. Framework like Angular and others set it by default. Check this in the doc https://laravel.com/docs/5.7/csrf#csrf-x-xsrf-tokenYou may like to use it.
知道有一个 X-XSRF-TOKEN cookie 是为了方便而设置的。Angular 等框架默认设置它。在文档https://laravel.com/docs/5.7/csrf#csrf-x-xsrf-token 中查看您可能喜欢使用它。
The best way is to use the meta, case the cookies are deactivated.
最好的方法是使用元,以防 cookie 被停用。
var xsrfToken = decodeURIComponent(readCookie('XSRF-TOKEN'));
if (xsrfToken) {
$.ajaxSetup({
headers: {
'X-XSRF-TOKEN': xsrfToken
}
});
} else console.error('....');
Here the recommended meta way (you can put the field any way, but meta is quiet nice):
这里推荐的元方式(你可以以任何方式放置该字段,但元很安静):
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
Note the use of decodeURIComponent()
, it's decode from uri format which is used to store the cookie. [otherwise you will get an invalid payload exception in laravel].
注意 的使用decodeURIComponent()
,它是从用于存储 cookie 的 uri 格式解码的。[否则你会在 laravel 中得到一个无效的负载异常]。
Here the section about the csrf cookie in the doc to check : https://laravel.com/docs/5.7/csrf#csrf-x-csrf-token
这里有关文档中的 csrf cookie 的部分要检查:https://laravel.com/docs/5.7/csrf#csrf-x-csrf-token
Also here how laravel (bootstrap.js) is setting it for axios by default:
同样在这里,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');
}
you can go check resources/js/bootstrap.js
.
你可以去检查一下resources/js/bootstrap.js
。
And here read cookie function:
在这里读取 cookie 功能:
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;
}
回答by Gjaa
Add an id
to the meta
element that holds the token
id
向meta
包含令牌的元素添加一个
<meta name="csrf-token" id="csrf-token" content="{{ csrf_token() }}">
And then you can get it in your Javascript
然后你可以在你的 Javascript 中得到它
$.ajax({
url : "your_url",
method:"post",
data : {
"_token": $('#csrf-token')[0].content //pass the CSRF_TOKEN()
},
...
});
回答by AMIB
if you are using jQuery to send AJAX Posts, add this code to all views:
如果您使用 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, '\'); };
var match = document.cookie.match(RegExp('(?:^|;\s*)' + escape(name) + '=([^;]*)'));
return match ? match[1] : null;
}
Laravel adds a XSRF cookie to all requests, and we automatically append it to all AJAX requests just before submit.
Laravel 为所有请求添加了一个 XSRF cookie,我们会在提交之前自动将其附加到所有 AJAX 请求。
You may replace getCookie function if there is another function or jQuery plugin to do the same thing.
如果有另一个函数或 jQuery 插件来做同样的事情,你可以替换 getCookie 函数。
回答by Udo E.
For Laravel 5.8, setting the csrf meta tag for your layout and setting the request header for csrf in ajax settings won't work if you are using ajax to submit a form that already includes a _token
input field generated by the Laravel blade templating engine.
对于 Laravel 5.8,如果您使用 ajax 提交已经包含_token
由 Laravel 刀片模板引擎生成的输入字段的表单,则为您的布局设置 csrf 元标记和在 ajax 设置中设置 csrf 的请求标头将不起作用。
You must include the already generated csrf token from the form with your ajax request because the server would be expecting it and not the one in your meta tag.
您必须在 ajax 请求中包含表单中已经生成的 csrf 令牌,因为服务器会期待它,而不是元标记中的那个。
For instance, this is how the _token
input field generated by Blade looks like:
例如,_token
Blade 生成的输入字段如下所示:
<form>
<input name="_token" type="hidden" value="cf54ty6y7yuuyyygytfggfd56667DfrSH8i">
<input name="my_data" type="text" value="">
<!-- other input fields -->
</form>
You then submit your form with ajax like this:
然后,您使用 ajax 提交表单,如下所示:
<script>
$(document).ready(function() {
let token = $('form').find('input[name="_token"]').val();
let myData = $('form').find('input[name="my_data"]').val();
$('form').submit(function() {
$.ajax({
type:'POST',
url:'/ajax',
data: {_token: token, my_data: myData}
// headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}, // unnecessary
// other ajax settings
});
return false;
});
});
</script>
The csrf token in the meta header is only useful when you are submitting a form without a Blade generated _token
input field.
元标题中的 csrf 令牌仅在您提交没有 Blade 生成的_token
输入字段的表单时才有用。
回答by myself
I just use @csrf inside the form and its working fine
我只是在表单中使用 @csrf 并且它工作正常