Closed JeanMertz closed 12 years ago
It sounds like your browser is making a preflighted request, which will be an OPTIONS request, but that should only happen on non get requests.
Well, it only happens with the custom Sync override. Without it, a normal GET request is sent (but without the CSFR token)
I still haven't solved this issue, but I am only using the backbone_rails_sync.js
and backbone_datalink.js
files from this repository. Could that cause this issue?
Also, looking at the source code for backbone_rails_sync.js
, if I do this:
// Make the request.
console.log(params);
return $.ajax(params);
It returns:
Object
beforeSend: function ( xhr ) {
complete: function (jqXHR, textStatus) {
dataType: "json"
error: function (model, resp) {
parse: true
success: function (resp, status, xhr) {
type: "GET"
url: "http://api.myapp.dev/projects"
__proto__: Object
The params
clearly show type: GET
and dataType: JSON
, yet the next line when $.ajax(params)
is fired, the server logs show:
Started OPTIONS "/projects" for 127.0.0.1 at 2012-04-21 13:24:07 +0200
Any more ideas?
Actually, it seems this issue is due to using CORS, see: http://metajack.im/2010/01/19/crossdomain-ajax-for-xmpp-http-binding-made-easy/
Still though, it doesn't happen without the backbone_rails_sync.js
file, so I'll see if there is a way around this and apply a pull request if I can fix this.
Well, it seems this is the part that causes the problems:
beforeSend: function( xhr ) {
var token = $('meta[name="csrf-token"]').attr('content');
if (token) xhr.setRequestHeader('X-CSRF-Token', token);
model.trigger('sync:start');
}
To be more precise, it's the part that sets the request header
. So it seems that this can't be fixed from the client side. I did find a solution for Rails developers, but the same principle applies to all servers that wan't to use CORS with this gem.
Basically what I've done is create a catch-all route for OPTIONS
requests and return the correct CORS headers. But this does tax your server more, so if I DO find a better solution to this I will post it here.
I've actually built a couple of CORS servers in the past and in order to handle passing headers the browser will first make a preflight request. Your server needs to respond back saying what methods, headers, and origins are allowed.
I'm going to mark this as closed because this needs to be handled server side.
You are correct about the preflight part. It wasn't firing because apparently, the browse only does this when it isn't sure if a specific action is allowed or not.
So in the case of backbone-rails
, the default action is a simple GET
request with the standard http headers, for which the browser doesn't fire a preflight request. However, when you add the X-CSRF-Token
header, using setRequestHeader
, the browser asks the server if this header is allowed before sending the actual get request.
So this was what's happening in my case, so simply modifying the backend application to work with this OPTIONS
request was all that was needed.
I've been using the following function to access my API on a different subdomain (with CORS enabled on the server):
Then in the
Collection
I use:The problem is, now this is showing up in my Rails log:
As you can see, it's supposed to show
Started GET "/projects"
, instead ofOPTIONS
, and without the customSync
method, this works, but not anymore. I am having a hard time finding the issue in the custom method, anyone know how to solve this? I can't be the only one wanting to access my Rails app form a different subdomain?I know I can use full domains for the
url
property, but I rather not specify the full url everywhere when I will always be using this subdomain.