小编典典

Rails无法在Ajax帖子上重新加载会话

ajax

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

我的Rails应用程序使用cookie会话存储,并且我有一个非常简单的登录名,用于设置会话中的用户ID。如果未在会话中设置user_id,它将重定向到登录页面。这没有问题。jQuery
GET请求也可以正常工作。问题是当我执行jQuery POST时-
浏览器将会话Cookie正常发送(我已通过Firebug确认并将cookie.dumps.cookies转储到日志中),但是会话为空,即会话为{}。

我正在我的application.js中执行此操作:

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

这是我的示例帖子:

$.post('/test/1', { _method: 'delete' }, null, 'json');

应该使用该控制器方法(_method:delete):

def destroy
  respond_to do |format|
    format.json { render :json => { :destroyed => 'ok' }.to_json }
  end
end

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

我已经尝试了所有可以想到的方法来调试它,但是我想到了这可能是Rails中的错误。如果有帮助,我正在使用Rails 3.0.4和jQuery
1.5。我发现非常奇怪的是,常规(即非ajax)获取和发布请求可以正常工作,而ajax get请求可以正常运行,只是ajax发布不起作用。

试图解决此问题的任何帮助将不胜感激!

非常感谢,
戴夫


阅读 283

收藏
2020-07-26

共1个答案

小编典典

我将回答自己的问题,因为我已经设法弄清了正在发生的事情。如果对其他人有用,我会在这里发布!

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

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

发生的事情是此代码未设置标头,Rails正在接收Ajax请求,令牌不匹配,并且正在重置会话。这曾经引发一个ActionController ::
InvalidAuthenticityToken错误(如果引发错误,我想我会早点抓到这个……好吧),但是自从Rails
3.0.4起,它现在只是悄悄地重置了会话。

因此,要在标头中发送令牌,您必须执行此操作(非常感谢这篇出色的博客文章):

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

现在一切正常。很好

2020-07-26