kba*_*che 232 jquery ruby-on-rails csrf
我用AJAX从视图向控制器发送数据我得到了这个错误:
警告:无法验证CSRF令牌的真实性
我想我必须发送带有数据的令牌.
有谁知道我该怎么做?
编辑:我的解决方案
我通过将以下代码放在AJAX帖子中来完成此操作:
headers: {
'X-Transaction': 'POST Example',
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
Run Code Online (Sandbox Code Playgroud)
小智 366
你应该做这个:
确保<%= csrf_meta_tag %>
您的布局中有
添加beforeSend
到所有ajax请求以设置标题如下:
$.ajax({ url: 'YOUR URL HERE',
type: 'POST',
beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))},
data: 'someData=' + someData,
success: function(response) {
$('#someDiv').html(response);
}
});
Run Code Online (Sandbox Code Playgroud)
要在所有请求中发送令牌,您可以使用:
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
Run Code Online (Sandbox Code Playgroud)
ADA*_*DAM 31
实现此目的的最佳方法实际上就是<%= form_authenticity_token.to_s %>
直接在rails代码中打印令牌.你不需要使用javascript来搜索dom中的csrf令牌,正如其他帖子所提到的那样.只需添加标题选项,如下所示;
$.ajax({
type: 'post',
data: $(this).sortable('serialize'),
headers: {
'X-CSRF-Token': '<%= form_authenticity_token.to_s %>'
},
complete: function(request){},
url: "<%= sort_widget_images_path(@widget) %>"
})
Run Code Online (Sandbox Code Playgroud)
aur*_*bee 22
如果我没记错的话,你必须在表单中添加以下代码,以解决这个问题:
<%= token_tag(nil) %>
Run Code Online (Sandbox Code Playgroud)
不要忘记参数.
小智 15
确实最简单的方法.不要在改变标题时烦恼.
确保你有:
<%= csrf_meta_tag %> in your layouts/application.html.erb
Run Code Online (Sandbox Code Playgroud)
只做一个隐藏的输入字段,如下所示:
<input name="authenticity_token"
type="hidden"
value="<%= form_authenticity_token %>"/>
Run Code Online (Sandbox Code Playgroud)
或者如果你想要一个jQuery ajax帖子:
$.ajax({
type: 'POST',
url: "<%= someregistration_path %>",
data: { "firstname": "text_data_1", "last_name": "text_data2", "authenticity_token": "<%= form_authenticity_token %>" },
error: function( xhr ){
alert("ERROR ON SUBMIT");
},
success: function( data ){
//data response can contain what we want here...
console.log("SUCCESS, data="+data);
}
});
Run Code Online (Sandbox Code Playgroud)
Dan*_*nny 13
从较旧的应用程序升级到rails 3.1,包括csrf元标记仍然没有解决它.在rubyonrails.org博客上,他们提供了一些升级提示,特别是这一行jquery应该放在你的布局的head部分:
$(document).ajaxSend(function(e, xhr, options) {
var token = $("meta[name='csrf-token']").attr("content");
xhr.setRequestHeader("X-CSRF-Token", token);
});
Run Code Online (Sandbox Code Playgroud)
取自这篇博文:http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails.
在我的情况下,会话正在重置每个ajax请求.添加上面的代码解决了这个问题.
nat*_*vda 10
<%= csrf_meta_tag %>
您的布局中有beforeSend
以在ajax请求中包含csrf-token以设置标头.这仅适用于post
请求.读取csrf-token的代码可以使用rails/jquery-ujs
,因此最简单的方法是使用它,如下所示:
$.ajax({
url: url,
method: 'post',
beforeSend: $.rails.CSRFProtection,
data: {
// ...
}
})
Run Code Online (Sandbox Code Playgroud)
我只是想把这个链接到这里,因为这篇文章有你想要的大部分答案,而且它也很有趣
此处的最高投票答案是正确的,但如果您执行跨域请求将无法工作,因为除非您明确告诉jQuery传递会话cookie,否则会话将不可用.以下是如何做到这一点:
$.ajax({
url: url,
type: 'POST',
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
},
xhrFields: {
withCredentials: true
}
});
Run Code Online (Sandbox Code Playgroud)
如果您不使用 jQuery 并使用fetch API 之类的请求,您可以使用以下方法获取csrf-token
:
document.querySelector('meta[name="csrf-token"]').getAttribute('content')
fetch('/users', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')},
credentials: 'same-origin',
body: JSON.stringify( { id: 1, name: 'some user' } )
})
.then(function(data) {
console.log('request succeeded with JSON response', data)
}).catch(function(error) {
console.log('request failed', error)
})
Run Code Online (Sandbox Code Playgroud)
哎呀..
我错过了 application.js 中的以下行
//= require jquery_ujs
Run Code Online (Sandbox Code Playgroud)
我更换了它,它的工作原理..
======== 更新 ==========
5 年后,我又回到了同样的错误,现在我有了全新的Rails 5.1.6,我又找到了这篇文章。就像生活圈一样。
现在的问题是: Rails 5.1默认删除了对jquery和jquery_ujs的支持,并添加了
//= require rails-ujs in application.js
Run Code Online (Sandbox Code Playgroud)
它执行以下操作:
但是为什么它不包括 ajax 请求的 csrf 令牌?如果有人详细了解这一点,请评论我。我很感激。
无论如何,我在我的自定义 js 文件中添加了以下内容以使其工作(感谢其他答案帮助我获得此代码):
$( document ).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-Token': Rails.csrfToken()
}
});
----
----
});
Run Code Online (Sandbox Code Playgroud)
您可以像下面这样全局地编写它。
普通JS:
$(function(){
$('#loader').hide()
$(document).ajaxStart(function() {
$('#loader').show();
})
$(document).ajaxError(function() {
alert("Something went wrong...")
$('#loader').hide();
})
$(document).ajaxStop(function() {
$('#loader').hide();
});
$.ajaxSetup({
beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))}
});
});
Run Code Online (Sandbox Code Playgroud)
咖啡脚本:
$('#loader').hide()
$(document).ajaxStart ->
$('#loader').show()
$(document).ajaxError ->
alert("Something went wrong...")
$('#loader').hide()
$(document).ajaxStop ->
$('#loader').hide()
$.ajaxSetup {
beforeSend: (xhr) ->
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
}
Run Code Online (Sandbox Code Playgroud)