jQuery 警告:无法验证 CSRF 令牌真实性导轨
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7203304/
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
WARNING: Can't verify CSRF token authenticity rails
提问by kbaccouche
I am sending data from view to controller with AJAXand I got this error:
我正在使用 AJAX 将数据从视图发送到控制器,但出现此错误:
WARNING: Can't verify CSRF token authenticity
警告:无法验证 CSRF 令牌的真实性
I think I have to send this token with data.
我想我必须将此令牌与数据一起发送。
Does anyone know how can I do this ?
有谁知道我该怎么做?
Edit: My solution
编辑:我的解决方案
I did this by putting the following code inside the AJAX post:
我通过将以下代码放在 AJAX 帖子中来做到这一点:
headers: {
'X-Transaction': 'POST Example',
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
回答by Chau Hong Linh
You should do this:
你应该做这个:
Make sure that you have
<%= csrf_meta_tag %>
in your layoutAdd
beforeSend
to all the ajax request to set the header like below:
确保
<%= 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);
}
});
To send token in all requests you can use:
要在所有请求中发送令牌,您可以使用:
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
回答by ADAM
The best way to do this is actually just use <%= form_authenticity_token.to_s %>
to print out the token directly in your rails code. You dont need to use javascript to search the dom for the csrf token as other posts mention. just add the headers option as below;
执行此操作的最佳方法实际上只是使用<%= 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) %>"
})
回答by auralbee
If I remember correctly, you have to add the following code to your form, to get rid of this problem:
如果我没记错的话,您必须将以下代码添加到您的表单中,以摆脱这个问题:
<%= token_tag(nil) %>
Don't forget the parameter.
不要忘记参数。
回答by Walter Schreppers
Indeed simplest way. Don't bother with changing the headers.
确实是最简单的方法。不要费心更改标题。
Make sure you have:
确保你有:
<%= csrf_meta_tag %> in your layouts/application.html.erb
Just do a hidden input field like so:
只需像这样做一个隐藏的输入字段:
<input name="authenticity_token"
type="hidden"
value="<%= form_authenticity_token %>"/>
Or if you want a jQuery ajax post:
或者,如果您想要一个 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);
}
});
回答by Danny
Ugrading from an older app to rails 3.1, including the csrf meta tag is still not solving it. On the rubyonrails.org blog, they give some upgrade tips, and specifically this line of jquery which should go in the head section of your layout:
从旧的应用程序升级到 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);
});
taken from this blog post: http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails.
取自这篇博文:http: //weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails。
In my case, the session was being reset upon each ajax request. Adding the above code solved that issue.
就我而言,每次 ajax 请求都会重置会话。添加上面的代码解决了这个问题。
回答by nathanvda
- Make sure that you have
<%= csrf_meta_tag %>
in your layout - Add a
beforeSend
to include the csrf-token in the ajax request to set the header. This is only required forpost
requests.
- 确保
<%= csrf_meta_tag %>
您的布局中有 - 添加一个
beforeSend
在ajax请求中包含csrf-token来设置header。这仅对于post
请求是必需的。
The code to read the csrf-token is available in the rails/jquery-ujs
, so imho it is easiest to just use that, as follows:
读取 csrf-token 的代码在 中可用rails/jquery-ujs
,所以恕我直言,最容易使用它,如下所示:
$.ajax({
url: url,
method: 'post',
beforeSend: $.rails.CSRFProtection,
data: {
// ...
}
})
回答by sciritai
I just thought I'd link this here as the article has most of the answer you're looking for and it's also very interesting
我只是想把这个链接到这里,因为这篇文章包含了你正在寻找的大部分答案,而且它也很有趣
回答by dreadwail
The top voted answers here are correct but will not work if you are performing cross-domainrequests because the session will not be available unless you explicitly tell jQuery to pass the session cookie. Here's how to do that:
此处投票最高的答案是正确的,但如果您正在执行跨域请求,则不会起作用,因为除非您明确告诉 jQuery 传递会话 cookie,否则会话将不可用。以下是如何做到这一点:
$.ajax({
url: url,
type: 'POST',
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
},
xhrFields: {
withCredentials: true
}
});
回答by Abhi
oops..
哎呀..
I missed the following line in my application.js
我错过了 application.js 中的以下行
//= require jquery_ujs
I replaced it and its working..
我更换了它,它的工作原理..
======= UPDATED =========
======== 更新 ==========
After 5 years, I am back with Same error, now I have brand new Rails 5.1.6, and I found this post again. Just like circle of life.
5 年后,我又回到了同样的错误,现在我有了全新的Rails 5.1.6,我又找到了这篇文章。就像生活圈一样。
Now what was the issue is: Rails 5.1removed support for jqueryand jquery_ujsby default, and added
现在的问题是: Rails 5.1默认删除了对jquery和jquery_ujs的支持,并添加了
//= require rails-ujs in application.js
It does the following things:
它执行以下操作:
- force confirmation dialogs for various actions;
- make non-GET requests from hyperlinks;
- make forms or hyperlinks submit data asynchronously with Ajax;
- have submit buttons become automatically disabled on form submit to prevent double-clicking. (from: https://github.com/rails/rails-ujs/tree/master)
- 各种动作的强制确认对话框;
- 从超链接发出非 GET 请求;
- 使表单或超链接与 Ajax 异步提交数据;
- 提交按钮在表单提交时自动禁用以防止双击。(来自:https: //github.com/rails/rails-ujs/tree/master)
But why is it not including the csrf token for ajax request? If anyone know about this in detail just comment me. I appreciate that.
但是为什么它不包括 ajax 请求的 csrf 令牌?如果有人详细了解这一点,请评论我。我很感激。
Anyway I added the following in my custom js file to make it work (Thanks for other answers to help me reach this code):
无论如何,我在我的自定义 js 文件中添加了以下内容以使其工作(感谢其他答案帮助我获得此代码):
$( document ).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-Token': Rails.csrfToken()
}
});
----
----
});
回答by Chezhian
You can write it globally like below.
您可以像下面这样全局编写它。
Normal JS:
普通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'))}
});
});
Coffee Script:
咖啡脚本:
$('#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'))
}