7

Follow by this question How to set access-control-allow-origin in webrick under rails?, I can GET and POST from the localhost to the localhost:3000.

However, the error occurred with DELETE and PUT

This is how i allow to cross domain access

class ApplicationController < ActionController::Base
    protect_from_forgery
    before_filter :allow_cross_domain_access
    def allow_cross_domain_access
        response.headers["Access-Control-Allow-Origin"] = "*"
        response.headers["Access-Control-Allow-Methods"] = "*"
    end
end

Any idea how to fix it?

Community
  • 1
  • 1
Hoan Dang
  • 2,222
  • 5
  • 27
  • 36

2 Answers2

11

* is not a valid value for the Access-Control-Allow-Methods response header. You need to list the actual methods:

response.headers["Access-Control-Allow-Methods"] = "GET, PUT, POST, DELETE"

Also if your request has any custom request headers, you will need to list those as well:

response.headers["Access-Control-Allow-Headers"] = "Content-Type, X-Requested-With"

Lastly note that your controller should allow OPTIONS http requests. This is to allow CORS preflight requests, which are required when making PUT or DELETE requests.

monsur
  • 45,581
  • 16
  • 101
  • 95
  • 1
    If * is not a valid value for the header 'access-control-allow-methods' could you explain why Chrome no longer throws a cross domain error when requesting a resource across domains with the code above that the questioner asked? His code seems to work for me and I'm trying to understand what the "right" way to do it, and why – n00b Apr 20 '13 at 20:12
  • 1
    @n00b The code above only applies to CORS preflight requests. If your request is a simple CORS request, there is no preflight. – monsur Apr 24 '13 at 01:21
9

This solution (http://www.tsheffler.com/blog/?p=428) works for me:

before_filter :cors_preflight_check
after_filter :cors_set_access_control_headers

# For all responses in this controller, return the CORS access control headers.

def cors_set_access_control_headers
  headers['Access-Control-Allow-Origin'] = '*'
  headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
  headers['Access-Control-Max-Age'] = "1728000"
end

# If this is a preflight OPTIONS request, then short-circuit the
# request, return only the necessary headers and return an empty
# text/plain.

def cors_preflight_check
  if request.method == :options
    headers['Access-Control-Allow-Origin'] = '*'
    headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
    headers['Access-Control-Allow-Headers'] = 'X-Requested-With, X-Prototype-Version'
    headers['Access-Control-Max-Age'] = '1728000'
    render :text => '', :content_type => 'text/plain'
  end
end

Also, probably you want to enable CORS in selected methods:

before_filter :cors_preflight_check, :only => [ :my_method]
after_filter :cors_set_access_control_headers, :only => [ :my_method]

I hope it helps

Aldo
  • 704
  • 6
  • 7