我在使用 jQuery 时遇到了 Rails 和 ajax 一个非常奇怪的问题(虽然我不认为它特定于 jQuery)。
我的 Rails 应用程序使用 cookie session 存储,我有一个非常简单的登录,它在 session 中设置用户 ID。如果 session 中未设置 user_id,它会重定向到登录页面。这没有问题。 JQuery GET 请求也能正常工作。问题是当我执行 jQuery POST 时 - 浏览器发送 session cookie 正常(我用 Firebug 确认了这一点并将 request.cookies 转储到日志)但 session 是空白的,即 session 是 {}。
我在我的 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');
应该到达这个 Controller 方法(_method:delete):
def destroy
respond_to do |format|
format.json { render :json => { :destroyed => 'ok' }.to_json }
end
end
查看日志并使用 Firebug 我可以确认在发生 ajax post 时在请求 header 中发送了正确的 cookie 值,但似乎在某些时候 Rails 丢失了这个值并因此丢失了 session ,所以它重定向到登录页面,永远不会进入该方法。
我已经尝试了所有我能想到的方法来调试它,但我开始意识到这可能是 Rails 中的一个错误。如果有帮助,我正在使用 Rails 3.0.4 和 jQuery 1.5。我发现常规(即非 ajax)获取和发布请求工作很奇怪,而 ajax 获取请求工作没有问题,只是 ajax 发布没有。
任何试图解决此问题的帮助将不胜感激!
非常感谢,
戴夫
最佳答案
我将回答我自己的问题,因为我已经设法弄清楚发生了什么。我会把它贴在这里,以防对其他人有用!
在进一步调查之后,我发现应该使用 CSRF token 设置请求 header 的代码不是。这是原始代码:
$(document).ajaxSend(function(e, xhr, options) {
var token = $("meta[name='csrf-token']").attr('content');
xhr.setRequestHeader('X-CSRF-Token', token);
});
发生的事情是这段代码没有设置 header ,Rails 正在接收 Ajax 请求, token 不匹配并且正在重置 session 。这曾经引发 ActionController::InvalidAuthenticityToken 错误(我想如果引发错误,我会更早地捕捉到这一点......哦,好吧),但从 Rails 3.0.4 开始,它现在只是安静地重置 session 。
因此,要在 header 中发送 token ,您必须这样做(非常感谢 this marvellous blog post ):
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
}
});
现在一切正常。这很好。
关于ruby-on-rails - Rails 不会在 ajax 帖子上重新加载 session ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5126721/