我用AJAXand发送数据从视图到控制器,我得到了这个错误:

警告:无法验证CSRF令牌的真实性

我想我必须用数据发送这个令牌。

有人知道我该怎么做吗?

编辑:我的解决方案

我通过在AJAX帖子中放入以下代码来做到这一点:

headers: {
  'X-Transaction': 'POST Example',
  'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},

当前回答

确实是最简单的方法。不要费心更改头文件。

确保你有:

<%= csrf_meta_tag %> in your layouts/application.html.erb

只需要像这样做一个隐藏的输入字段:

<input name="authenticity_token" 
               type="hidden" 
               value="<%= form_authenticity_token %>"/>

或者如果你想要一个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);
    }
});

其他回答

确保在布局中有<%= csrf_meta_tag %> 添加beforeSend在ajax请求中包含csrf-令牌,以设置头部。这只需要post请求。

读取csrf-token的代码在rails/jquery-ujs中可用,所以以我之见,使用它是最简单的,如下所示:

$.ajax({
  url: url,
  method: 'post',
  beforeSend: $.rails.CSRFProtection,
  data: {
    // ...
  }
})

对于那些需要非jQuery答案的人,您可以简单地添加以下内容:

xmlhttp.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));

这里有一个非常简单的例子:

xmlhttp.open("POST","example.html",true);
xmlhttp.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
xmlhttp.send();

从一个旧的应用程序升级到rails 3.1,包括csrf元标记仍然不能解决这个问题。在rubyonrails.org的博客上,他们给出了一些升级技巧,特别是这一行jquery应该放在布局的头部部分:

$(document).ajaxSend(function(e, xhr, options) {
 var token = $("meta[name='csrf-token']").attr("content");
  xhr.setRequestHeader("X-CSRF-Token", token);
});

摘自这篇博客:http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails。

在我的例子中,会话在每次ajax请求时都被重置。添加上面的代码解决了这个问题。

我为这个问题纠结了好几天。任何GET调用都正常工作,但所有put都会生成“无法验证CSRF令牌真实性”错误。在我向nginx添加SSL证书之前,我的网站工作正常。

我终于在nginx设置中发现了这一行:

location @puma { 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header Host $http_host; 
    proxy_redirect off;
    proxy_set_header X-Forwarded-Proto https;   # Needed to avoid 'WARNING: Can't verify CSRF token authenticity'
    proxy_pass http://puma; 
}

在添加了缺失的行“proxy_set_header X-Forwarded-Proto https;”之后,我的所有CSRF令牌错误都退出了。

希望这能帮助那些也在用头撞墙的人。哈哈

哎呀. .

我在我的application.js中漏掉了下面一行

//= require jquery_ujs

我把它换了,它还在工作。

=======更新=========

5年后,我又犯了同样的错误,现在我有了全新的Rails 5.1.6,我又找到了这篇文章。就像生命的循环。

现在的问题是 Rails 5.1默认删除了对jquery和jquery_ujs的支持

//= require rails-ujs in application.js

它做以下事情:

各种操作的强制确认对话框; 从超链接发出非get请求; 使用Ajax使表单或超链接异步提交数据; 在表单提交时自动禁用提交按钮,以防止双击。 (来自https://github.com/rails/rails-ujs/tree/master):

但为什么它不包括csrf令牌ajax请求?如果有人知道这个细节,请评论我。我很感激。

无论如何,我在我的自定义js文件中添加了以下内容以使其工作(感谢其他帮助我实现此代码的答案):

$( document ).ready(function() {
  $.ajaxSetup({
    headers: {
      'X-CSRF-Token': Rails.csrfToken()
    }
  });
  ----
  ----
});