表单提交后更新 CSRF
Renew CSRF after form submit
我想实现我在该图像中显示的功能。用户将单击编辑按钮并激活页面中单个字段的表单。
使用Ajax我会更新一个模型,成功后会再次恢复显示。这里的问题是CSRF_TOKEN。用户更新第一个字段后,无论是哪个字段,第二次编辑都会 return 错误 500 令牌不匹配消息。
我尝试了很多不同的方法,包括我在这里看到的最后一种方法:
$.ajaxSetup( {
beforeSend: function( xhr, settings ){
function getCookie( name ){
var cookieValue = null;
if( document.cookie && document.cookie != '' ){
var cookies = document.cookie.split( ';' );
for( var i = 0; i < cookies.length; i++ ){
var cookie = jQuery.trim( cookies[ i ] );
// Does this cookie string begin with the name we want?
if( cookie.substring( 0, name.length + 1 ) == ( name + '=' ) ){
cookieValue = decodeURIComponent( cookie.substring( name.length + 1 ) );
break;
}
}
}
return cookieValue;
}
if( !( /^http:.*/.test( settings.url ) || /^https:.*/.test( settings.url ) ) ){
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader( "X-CSRFToken", getCookie( 'csrftoken' ) );
}
}
} );
但我仍然在第二次提交时收到错误。我知道我需要做的就是在我的元 <meta name="csrf-token" content="{{ csrf_token() }}">
中更新令牌的值,但我 运行 不知道如何去做,我真的想在不刷新页面的情况下保留这个功能。
也许可以从控制器发送新的 CSRF,它是 return 的结果,并在 ajax 请求的成功阶段使用类似 $( 'meta[name="csrf-token"]' ).val( response.csrf );
的内容?
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
}
});
我的回答包括修改至少两个文件,执行 ajax 的模板和接收表单请求的控制器。从页面中的表单接收操作的所有方法都应该 return 更新的 csrf 令牌和包含 csrf 值的所有字段(如果有的话)也应该在 ajax 执行后更新。
首先,blade 模板将对文档中的所有表单使用通用的 csrf 标记,为此,我将元 csrf-token 添加到我的 header 部分,如下所示通常:
<meta name="csrf-token" content="{{ csrf_token() }}">
现在,ajax 脚本必须在模板中的任何表单执行后插入令牌并更新元数据:
$( 'body' ).on( 'submit', '.form', function( event ){
event.preventDefault();
let fd = new FormData( $( this )[ 0 ] );
fd.append( '_token', $( 'meta[name="csrf-token"]' ).attr( 'content' ) )
$.ajax( {
url : '{{ route( 'service.update', [ 'service' => $service ] ) }}',
method : 'post',
data : fd,
contentType: false,
processData: false,
success: function( response ){
$( 'meta[name="csrf-token"]' ).attr( 'content', response.token );
//Do all the other things that need to be done...
},
error: function( xhr, status, error ){
console.log( error );
}
} );
} );
现在,我做的第一件事是创建一个包含表单内容的 FormData
object,并将元数据中的 csrf 值添加到字段集 (fd.append( '_token', $( 'meta[name="csrf-token"]' ).attr( 'content' ) )
)。
执行完成后,我的 javascript 将收到一个带有 .token 值的响应变量,其中包含新的 csrf-token 值,所以我用新的元值更新旧的元值: $( 'meta[name="csrf-token"]' ).attr( 'content', response.token );
.
现在,对于控制器端,我需要做的就是将令牌值添加到 jSon,在我的例子中它是一个数组,所以我只需要像这样添加它:
$response[ 'token' ] = $request->session()->token();
return $response;
现在表格可以正常工作了,谢谢
我想实现我在该图像中显示的功能。用户将单击编辑按钮并激活页面中单个字段的表单。
使用Ajax我会更新一个模型,成功后会再次恢复显示。这里的问题是CSRF_TOKEN。用户更新第一个字段后,无论是哪个字段,第二次编辑都会 return 错误 500 令牌不匹配消息。
我尝试了很多不同的方法,包括我在这里看到的最后一种方法:
$.ajaxSetup( {
beforeSend: function( xhr, settings ){
function getCookie( name ){
var cookieValue = null;
if( document.cookie && document.cookie != '' ){
var cookies = document.cookie.split( ';' );
for( var i = 0; i < cookies.length; i++ ){
var cookie = jQuery.trim( cookies[ i ] );
// Does this cookie string begin with the name we want?
if( cookie.substring( 0, name.length + 1 ) == ( name + '=' ) ){
cookieValue = decodeURIComponent( cookie.substring( name.length + 1 ) );
break;
}
}
}
return cookieValue;
}
if( !( /^http:.*/.test( settings.url ) || /^https:.*/.test( settings.url ) ) ){
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader( "X-CSRFToken", getCookie( 'csrftoken' ) );
}
}
} );
但我仍然在第二次提交时收到错误。我知道我需要做的就是在我的元 <meta name="csrf-token" content="{{ csrf_token() }}">
中更新令牌的值,但我 运行 不知道如何去做,我真的想在不刷新页面的情况下保留这个功能。
也许可以从控制器发送新的 CSRF,它是 return 的结果,并在 ajax 请求的成功阶段使用类似 $( 'meta[name="csrf-token"]' ).val( response.csrf );
的内容?
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
}
});
我的回答包括修改至少两个文件,执行 ajax 的模板和接收表单请求的控制器。从页面中的表单接收操作的所有方法都应该 return 更新的 csrf 令牌和包含 csrf 值的所有字段(如果有的话)也应该在 ajax 执行后更新。
首先,blade 模板将对文档中的所有表单使用通用的 csrf 标记,为此,我将元 csrf-token 添加到我的 header 部分,如下所示通常:
<meta name="csrf-token" content="{{ csrf_token() }}">
现在,ajax 脚本必须在模板中的任何表单执行后插入令牌并更新元数据:
$( 'body' ).on( 'submit', '.form', function( event ){
event.preventDefault();
let fd = new FormData( $( this )[ 0 ] );
fd.append( '_token', $( 'meta[name="csrf-token"]' ).attr( 'content' ) )
$.ajax( {
url : '{{ route( 'service.update', [ 'service' => $service ] ) }}',
method : 'post',
data : fd,
contentType: false,
processData: false,
success: function( response ){
$( 'meta[name="csrf-token"]' ).attr( 'content', response.token );
//Do all the other things that need to be done...
},
error: function( xhr, status, error ){
console.log( error );
}
} );
} );
现在,我做的第一件事是创建一个包含表单内容的 FormData
object,并将元数据中的 csrf 值添加到字段集 (fd.append( '_token', $( 'meta[name="csrf-token"]' ).attr( 'content' ) )
)。
执行完成后,我的 javascript 将收到一个带有 .token 值的响应变量,其中包含新的 csrf-token 值,所以我用新的元值更新旧的元值: $( 'meta[name="csrf-token"]' ).attr( 'content', response.token );
.
现在,对于控制器端,我需要做的就是将令牌值添加到 jSon,在我的例子中它是一个数组,所以我只需要像这样添加它:
$response[ 'token' ] = $request->session()->token();
return $response;
现在表格可以正常工作了,谢谢