Reputation: 992
When I try to set my request header token, I receive an error:
ActionController::RoutingError (No route matches [OPTIONS] "/data"):
Here is the ajax call:
$.ajax({
url: this.hostName + url,
type: 'POST',
data: data,
dataType: 'json',
beforeSend: function( xhr ) {
xhr.setRequestHeader( 'X-CSRF-Token', $( 'meta[name="csrf-token"]' ).attr( 'content' ) );
},
success: function(response) {
console.log('success');
console.log(response);
},
error: function(response) {
console.log('error');
console.log(response);
}
});
If I leave the request header out:
Started POST "/data" for 127.0.0.1 at 2012-07-24 18:37:22 -0700
but I get a warning stating:
WARNING: Can't verify CSRF token authenticity
Any ideas as to why this is happening?
Upvotes: 1
Views: 4181
Reputation: 2117
You should try giving relative url instead of absolute in ajax. I had the same problem, and worked by changing url
Upvotes: 0
Reputation: 19203
Have you tried
$.ajax({
url: this.hostName + url,
type: 'POST',
headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') }
data: { param : 'something' },
dataType: 'json'
});
And then in your controller params[:param] will give you 'something'.
If you are interested to know why you need all that X-CSRF-Token stuff, this is a good read. Basically, Rails automatically includes that token in your page to keep your application safe. If you inspect any page of your site, you'll see in the head of your HTML document something like this:
<meta content="guma1QdmO9Tn9SB4yV4DonkY4xf4Sy6lIvrFyHIaR1U=" name="csrf-token">
This is created by the line <%= csrf_meta_tags %>
included in your application.html.erb
file.
Rails automatically includes this token in regular non-GET requests to keep them safe. But with javascript and ajax, you have to do this manually by searching the DOM for the token with the jQuery function $('meta[name="csrf-token"]'
.
Now, this isn't very efficient because you are searching for that token every time you are making a request. So what you should do, is use ajaxSetup, like this:
$.ajaxSetup({
type: 'POST',
headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') }
dataType: 'json'
});
And now, whenever you want to send a request, all you need is this:
$.ajax({
url: this.hostName + url,
data: { param : 'something' }
});
EDIT: Ah, I see. What do you get when you do alert(this.hostName + url)
? And how are you declaring your routes? Because if I remember correctly, you can use relative urls instead of absolute urls, you don't need the root part. Here's an example:
# routes.rb
post "relative_url" => 'controller#action'
# file.js
$.ajax({
url: "relative_url",
data: { param : 'something' }
});
Upvotes: 1