2013-11-09 123 views
3

我已经构建了一个轨道宁静的服务,我在Heroku和一个Angular客户机上进行托管,我试图从本地机器运行该服务。最终这个客户端将被添加到phonegap项目中。但是,现在我正在测试应用程序在铬和ie和我的浏览器不断返回下面的错误。Heroku Rails CORS问题

XMLHttpRequest cannot load Origin http://localhost is not allowed by Access-Control-Allow-Origin. 

这是我得到的错误消息。在推向Heroku之前,我遇到了这个问题,并通过向我的响应中添加访问标头来解决此问题。

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'] = 'http://localhost' #* 
     headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS' 
     headers['Access-Control-Allow-Headers'] = %w{Origin Accept Content-Type X-Requested-With X-CSRF-Token}.join(',') 
     headers['Access-Control-Max-Age'] = "1728000" 
end 

这似乎不起作用。出于某种原因,这与Heroku不兼容。有谁知道如何解决这个问题?

+0

你解决这个问题?我有同样的... – Featalion

+0

是的......我会在下面发布答案 – Lampbo

回答

2
class ApplicationController < ActionController::Base 
protect_from_forgery 
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-Allow-Headers'] = %w{Origin Accept Content-Type X-Requested-With auth_token X-CSRF-Token}.join(',') 
    headers['Access-Control-Max-Age'] = "1728000" 
end 

def cors_preflight_check 
    if request.method == "OPTIONS" 
    headers['Access-Control-Allow-Origin'] = 'http://localhost' 
    headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS' 
    headers['Access-Control-Allow-Headers'] = %w{Origin Accept Content-Type X-Requested-With auth_token X-CSRF-Token}.join(',') 
    headers['Access-Control-Max-Age'] = '1728000' 
    render :text => '', :content_type => 'text/plain' 
    end 
end 
end 

这似乎是个伎俩。

+0

是的,我看到了这个解决方案,但我不喜欢它。我将在下面添加我的解决方案。 – Featalion

6

Rails 4的可能解决方案之一(没有检查早期版本)。我使用rails-api来创建独立的API服务器。所以,基于ActionController::API的示例。在使用ActionController::Base的情况下,相同的解决方案必须正常工作。

# app/controllers/application_controller.rb 
class ApplicationController < ActionController::API 
    include ActionController::ImplicitRender 
    include ActionController::MimeResponds 

    def cors_preflight_check 
    headers['Access-Control-Max-Age'] = '1728000' 

    render json: {} # Render as you need 
    end 
end 


# config/application.rb 
class Application < Rails::Application 
    config.action_dispatch.default_headers = { 
    'Access-Control-Allow-Origin' => '*', 
    'Access-Control-Allow-Methods' => 'POST, PUT, PATCH, DELETE, GET, OPTIONS', 
    'Access-Control-Request-Method' => '*', 
    'Access-Control-Allow-Headers' => 'Origin, X-Requested-With, Content-Type, Accept, Authorization' 
    } 
end 


# config/routes.rb 
# Last route definition code line 
match '*path', to: 'application#cors_preflight_check', via: [:options] 

这个解决方案对我来说似乎不那么讨厌。另外,它在“Rails-way”中采用HTTP方法处理OPTIONS

+0

谢谢Featalion,它适用于我,虽然我不知道它是否会导致一些安全问题。我只修改了config/application.rb文件,然后从我的http:// localhost中创建了一个简单的XMLHttpRequest。 – wagyaoo

+0

哇,经过寻找似乎像天的一个解决方案与Herku一般问题的CORS,我偶然发现了这一点,并看!有用!谢谢,Featalion。 – eplewis89

+0

也适用于Rails 5 –