好的,所以在我的某个页面上的rails应用程序中,我需要传递一个Javascript变量,以便它可用于rails。现在一个运行服务器端,一个运行客户端,所以我知道这很困难。我查看了互联网,发现了一个解决方案,涉及在我的外部javascript页面中包含的函数中动态创建表单。
基本上,使用document.createElement
语句创建一个带有隐藏字段的表单,隐藏字段被赋予我想要传递给rails的值,然后调用form.submit()
以便表单是提交。该表格给出了一种邮政方法,并给它一条路去。因此,当提交它时,称为页面重定向到另一个页面,其中隐藏字段现在在params哈希中,并且可以通过带params[:param]
的rails访问。
这很有效,直到我们开始使用会话来跟踪登录用户。单击要使用该动态表单重定向的按钮后,会话将被清除。我在网上发现的关于被清除会话的唯一事情是当rails检测到CSRF时它会清除会话。
那么我正在做什么导致rails检测到CSRF并因此清除我的会话?有没有其他任何理由可以清除任何人都知道的会话?此外,没有ajax(因为我只是没有搞砸了它,它不能很好地播放。)是否有另一个好方法,我错过了传递一个javascript变量(它必须是javascript,我使用的是一个javascript函数来获取用户当前位置)以便它可用于rails? (我正在考虑而不是javascripting表单,我可能只是在我的页面上创建一个隐藏的表单,虽然这有点不那么优雅,因为任何看到源的人都可以看到它,并想知道为什么它在那里并拧紧它)< / p>
如果有人感兴趣,下面是我的动态表单函数的代码。
function post_to_url(path, params, method) {
method = method || "post"; // Set method to post by default, if not specified.
var form = document.createElement("form");
form.setAttribute("method", method);
form.setAttribute("action", path); //page to go redirect to when form submitted
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
//after form is submitted params is available by params[:location]
hiddenField.setAttribute("name", 'location');
hiddenField.setAttribute("value", params )
form.appendChild(hiddenField);
document.body.appendChild(form);
form.submit();
}
答案 0 :(得分:1)
以任何形式请求和ajax必须传递CSRF令牌。您需要在名称为authenticity_token
的表单中创建隐藏字段。然后,您需要从元标记中获取值:
<meta content="some_token_value" name="csrf-token" />
像这样:
var token = "";
var tags = document.getElementsByTagName("meta");
for(var i = 0; i < tags.length; i++) {
if(tags[i].name == "csrf-param") {
token = tags[i].content;
}
}
然后简单地将其放入隐藏标记的值中,就像您对位置值所做的那样。
答案 1 :(得分:0)
您可以在javascript文件中添加erb行:
var csrf_token = '<%= form_authenticity_token %>';
然后在您的请求中,在后期数据中添加'authenticity_token' : csrf_token
。