Rails没有在ajax帖子上重新加载会话

Dav*_*rth 61 ajax jquery ruby-on-rails

我正在使用jQuery遇到一个非常奇怪的Rails和ajax问题(尽管我认为它不是特定于jQuery).

我的Rails应用程序使用cookie会话存储,我有一个非常简单的登录,在会话中设置用户ID.如果未在会话中设置user_id,则会重定向到登录页面.这没有问题.JQuery GET请求也可以正常工作.问题是当我做一个jQuery POST时 - 浏览器发送会话cookie ok(我用Firebug确认了这个并将request.cookies转储到日志中)但会话是空白的,即session是{}.

我在我的application.js中这样做:

$(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)

这是我的样本帖子:

$.post('/test/1', { _method: 'delete' }, null, 'json');
Run Code Online (Sandbox Code Playgroud)

应该到达这个控制器方法(_method:delete):

def destroy
  respond_to do |format|
    format.json { render :json => { :destroyed => 'ok' }.to_json }
  end
end
Run Code Online (Sandbox Code Playgroud)

查看日志并使用Firebug我可以确认在ajax发布时在请求标头中发送了正确的cookie值,但似乎在某些时候Rails丢失了这个值并因此丢失了会话,因此它重定向到登录页面,永远不会到达方法.

我已经尝试了所有我能想到的东西来调试这个,但是我想到这可能是Rails中的一个错误.我正在使用Rails 3.0.4和jQuery 1.5,如果这有帮助的话.我发现定期(即非ajax)获取和发布请求工作非常奇怪,并且ajax获取请求工作没有问题,这只是ajax帖子没有.

任何帮助尝试解决这个问题将不胜感激!

非常感谢,
戴夫

Dav*_*rth 113

我将回答我自己的问题,因为我已经设法弄清楚发生了什么.我会在这里发布,以防它对其他人有用!

在进一步调查之后,我发现应该使用CSRF令牌设置请求标头的代码不是.这是原始代码:

$(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)

发生的事情是这个代码没有设置标头,Rails正在接收Ajax请求,令牌不匹配,它正在重置会话.这用于引发一个ActionController :: InvalidAuthenticityToken错误(我想如果出现错误,我会早点抓住这个......哦,好吧),但是自从Rails 3.0.4以来它现在只是悄悄地重置了会话.

因此,要在标题中发送令牌,您必须这样做(非常感谢这篇精彩的博客文章):

$.ajaxSetup({
  beforeSend: function(xhr) {
    xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
  }
}); 
Run Code Online (Sandbox Code Playgroud)

现在一切正常.这很好.


Siw*_*申思维 5

我找到了另一个案例:

你在应用程序布局文件中设置'csrf_meta_tag'了吗?

在我的情况下,我没有设置该标签,并遇到了与您相同的问题.

在app/views/layouts/application.html.erb中设置csrf_meta_tag之后,一切正常!

最后,谢谢你帮我找到了根本原因!非常感谢〜