Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails, Backbone, PhoneGap, CORS (not allowed by Access-Control-Allow-Origin error)

I'm building a Phonegap app in that uses backbone.js and a Rails backend. While creating new users, I am getting a CORS related error:

I am running my PhoneGap web app on http://0.0.0.0:8000 ($ python -m SimpleHTTPServer), and running my Rails app in webrick on http://0.0.0.0:3000 ($ rails server).

The problem happens when trying to create a new "Spot" in Backbone like this (chrome js console):

> s = new App.Models.Spot()
(creates Spot)
> s.save()
(returns error Object)
OPTIONS http://0.0.0.0:3000/spots.json 404 (Not Found) jquery-1.8.2.js:8416
XMLHttpRequest cannot load http://0.0.0.0:3000/spots.json. Origin http://0.0.0.0:8000 is not allowed by Access-Control-Allow-Origin.

Here is my application controller:

def set_access_control_headers
  headers['Access-Control-Allow-Origin'] = 'http://0.0.0.0:8000'
  headers['Access-Control-Request-Method'] = 'POST, GET'
end

I have read numerous articles, and the furthest along I could get was when modifying my routes.rb to include this:

match '*all' => 'application#cor', :constraints => {:method => 'OPTIONS'}

And in my application_controller.rb

def cor
  headers["Access-Control-Allow-Origin"] = "*"
  headers["Access-Control-Allow-Methods"] = %w{GET POST PUT DELETE OPTIONS}.join(",")
  headers["Access-Control-Allow-Headers"] = %w{Origin Accept Content-Type X-Requested-With X-CSRF-Token}.join(",")
  head(:ok) if request.request_method == "OPTIONS"
end

Adding the route and the 'cor' method will then allow me to make saves, but, I will have the same error when deleting records.

I get the basic idea of CORS, I can't access a server with a different domain than that of the origin of my request. But how exactly to set this up with Rails, Backbone, Phonegap, is not clear to me. Any help would be awesome, thanks!

like image 445
botbot Avatar asked Dec 17 '12 08:12

botbot


1 Answers

I've follow this article (section "CORS in Rails") and it works for me.

I change if request.method == :options to if request.method == 'OPTIONS' and add methods PUT, DELETE to headers['Access-Control-Allow-Methods']. Insted of '*' in Access-Control-Allow-Origin I have localhost:8080 (I'm running my app on nginx).

Hope this will help.

PD: Do you have filters (hooks) in your application controller?

like image 131
cortex Avatar answered Oct 01 '22 15:10

cortex