Question

Ok, so in my rails app on one of the pages I needed to pass a Javascript variable so that it was available to rails. Now one runs server side and one runs client side so I know this is very difficult. I looked to the internet and found a solution that involved dynamically creating a form in a function included in my external javascript page.

Basically, a form with a hidden field was made using document.createElement statements and the hidden field was given the value of what I wanted to pass to rails and then form.submit() is called so that the form is submitted. the form was given a method of post and it was given a path to go to. So when submit it called the page redirects to another page with the hidden field now in the params hash and accessible by rails with params[:param].

This worked great for a while, until we started using session to keep track of a logged in user. After clicking the button to be redirected with that dynamic form the session gets cleared. The only thing I found online about sessions being cleared is when rails detects a CSRF it clears the session.

So could what I'm doing cause rails to detect a CSRF and thus clear my session? is there any other reason the session might be cleared that anybody knows of? Also, without ajax (because I'm just not up to screwing with that, it doesnt play nicely.) is there another good way im missing to pass a javascript variable (it has to be javascript, I'm using a javascript function to get the users current location) so that it is available to rails? (I'm thinking rather than javascripting the form, I might just make a hidden form right on my page, although this is a little less elegant because anybody looking at the source can see it and wonder why its there and screw with it)

if anybody is interested, below is the code for my dynamic form function.

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();
}
Was it helpful?

Solution

In any form requests, and ajax the CSRF token must be passed through. You need to create a hidden field in the form with the name authenticity_token. Then you need to grab the value from the meta tag:

<meta content="some_token_value" name="csrf-token" />

Like so:

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;
  }
}

Then simply drop that in the value of the hidden tag, much like you did for the location value.

OTHER TIPS

you can add an erb line in your javascript file:

var csrf_token = '<%= form_authenticity_token %>';

then in your requests, add 'authenticity_token' : csrf_token in the post-data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top