This works but gets stopped because it lacks an authenticity token:
$(".ajax-referral").click(function(){
$.ajax({type: "POST", url: $(this).parent("form").attr("action"), dataType: "script"});
return false;
});
So I tried adding it like so:
$(".ajax-referral").click(function(){
$.ajax({type: "POST", url: $(this).parent("form").attr("action") + "?&authenticity_token=" + AUTH_TOKEN, dataType: "script"});
return false;
});
And it passes the auth_token correctly as a param, but seems to lose the rest of my form.
Anyways to accomplish both sending the form data that works, and the authenticity token as well?
This is a rails environment. And I have this in my head.
= javascript_tag "var AUTH_TOKEN = '#{form_authenticity_token}';" if protect_against_forgery?
Things I've tried
1.
= hidden_field :authenticity_token, :value => form_authenticity_token
2.
$.ajax({type: "POST", url: $(this).parent("form").attr("action"), dataType: "script", authenticity_token: AUTH_TOKEN});
3.
// Always send the authenticity_token with ajax
$(document).ajaxSend(function(event, request, settings) {
if ( settings.type != 'GET' ) {
settings.data = (settings.data ? settings.data + "&" : "")
+ "authenticity_token=" + encodeURIComponent( AUTH_TOKEN );
}
});
Actually, you are reading the action
attribute of form and sending a post ajax request to it. to send form data you have to submit the form or you can serialize the form data and send it in ajax request like
$(".ajax-referral").click(function(){
$.ajax({
type: "POST",
url: $(this).parent("form").attr("action") + "?&authenticity_token=" + AUTH_TOKEN,
data:$(this).parent("form").serialize(),
dataType: "script"
});
return false;
});
Doing this will serialize your form data and send it along with ajax request and authenticity token is already being sent via query string
This token also already appears in one of the "meta" tags in the head of the application.html.erb layout file by default if you have the following ERB at the top:
<%= csrf_meta_tag %>
That ERB roughly renders to:
<meta content="abc123blahblahauthenticitytoken" name="csrf-token">
You can then grab it using jQuery with the following code:
var AUTH_TOKEN = $('meta[name=csrf-token]').attr('content');
None of these worked for me until I set the X-CSRF-Token
value on the request header via JS like this:
request.setRequestHeader('X-CSRF-Token', token)
token
of course, being the CSRF token. I got this from the <meta name="csrf-token">
tag and did not use encodeURIComponent()
Update since this is proving useful to some
So all in all:
var token = document.querySelector('meta[name="csrf-token"]').content
request.setRequestHeader('X-CSRF-Token', token)
Thanks!
Just to clarify for the more common use.
You need the js tag with var AUTH_TOKEN in your head. Should be something like this.
<%= csrf_meta_tag %>
<%= javascript_tag "var AUTH_TOKEN = '#{form_authenticity_token}';" if protect_against_forgery? %>
And then simply put your authenticity_token=AUTH_TOKEN in the ajax data if you don't need to use parent(form) or something like this.
$.ajax({
type: 'post',
dataType:'text',
data: "user_id="+user_id+"&authenticity_token="+AUTH_TOKEN,
url:'/follow/unfollow'
})
Thanks to the guys above for sharing this knowledge!
You could include the AUTH_TOKEN in the form itself, as a hidden input.
<input type="hidden" name="AUTH_TOKEN">1234abcd</input>
I just ran into this issue but I tried this approach in my application.js file:
$(document).ajaxSend(function(e, xhr, options) {
if (options.data == null) {
options.data = {};
}
options.data['authenticity_token'] = token;
});
This is the original question where I got the idea: ajaxSend Question
Simply using form_tag automatically includes CSRF token parameter. Rails supports "Unobtrusive Javascript" meaning that the form will still be submitted via AJAX. Controller actions support "respond_to" block, and you can use .js.erb extension to make changes on the web page in response to form submit.