在我的 Rails 应用程序中,我试图通过 AJAX 将 JSON 传递给控制器,但我遇到了401 (unauthorized)
错误。 我一直在研究这个问题,并试图弄清楚我做错了什么,但我不能完全说出来。
首先,AJAX 本身 -
$.ajax({
url: "report/submission",
type: "POST",
beforeSend: function(xhr) {xhr.setRequestHeader("X-CSRF-Token", $("meta[name='csrf-token']").attr("content"))},
data: {"report" : reportParameter}
});
这会将数据传递到Report
控制器中的submission
操作 -
class ReportController < ApplicationController
before_action :authenticate_user!, :only => [:submission]
def submission
INSERT ENTRIES TO DB, ETC
end
end
因此,也许一个复杂的因素是我需要before_action
Devise登录。
所以基本过程是,用户填写一个表单,将条目组装成 JSON(reportParameter
),然后传递给需要成功登录才能完成的submission
操作(我知道这可能看起来向后,但对于这个特定的应用程序是必要的)。
我的布局包括<%= csrf_meta_tags %>
,我在application
控制器中设置了protect_from_forgery with: :null_session
。
我必须承认,我对此的理解还不够好,无法更有洞察力 - 我知道这是一个与 CSRF 令牌相关的授权问题,但我认为在 AJAX 中设置beforeSend
可以解决这个问题。
任何指导将不胜感激。
如果您使用的是标准的Rails表单(form_tag
或form_for
),那么一个简单的方法是使用jquery-ujs
。默认情况下,它通常处于application.js
# application.js
//= require jquery_ujs
它会自动处理CSRF令牌,并添加到jQuery的ajax
方法(您手动执行的操作)。
如果您不想将application.js
文件包含在您的页面中,那么您可以简单地包含jquery-ujs.js
文件。
如果您也不想这样做,那么我唯一能想到的是您的表单正在使用"旧"或"非最新"csrf 令牌(缓存表单可能有它们)。然后,确保隐藏形式的csrf令牌未提交或与您在请求标头中发送的令牌匹配。这是为了让你了解我的意思。