我在使用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发布不起作用。
试图解决此问题的任何帮助将不胜感激!
非常感谢, 戴夫
我将回答自己的问题,因为我已经设法弄清了正在发生的事情。如果对其他人有用,我会在这里发布!
经过进一步调查,我发现 应该 使用CSRF令牌设置请求标头的代码不是。这是原始代码:
发生的事情是此代码未设置标头,Rails正在接收Ajax请求,令牌不匹配,并且正在重置会话。这曾经引发一个ActionController :: InvalidAuthenticityToken错误(如果引发错误,我想我会早点抓到这个……好吧),但是自从Rails 3.0.4起,它现在只是悄悄地重置了会话。
因此,要在标头中发送令牌,您必须执行此操作(非常感谢这篇出色的博客文章):
$.ajaxSetup({ beforeSend: function(xhr) { xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content')); } });
现在一切正常。很好