XMLHttpRequest No' Access-Control-Allow-Origin'标头出现在请求的资源上

时间:2014-07-30 19:49:30

标签: javascript ruby-on-rails angularjs

所以StackOverflow上有一些问题可以解决这个错误,但是在我检查过的10-15个问题中,我无法找到解决我的确切问题的方法。

我在远程服务器上运行Angular应用程序(端口9000)和Rails应用程序(端口3000)。角度应用程序通过邮寄请求向rails应用程序发送请求。

发出请求时,Javascript控制台会显示以下错误消息:

XMLHttpRequest cannot load http://0.0.0.0:3000/api/query. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://10.241.16.159:9000' is therefore not allowed access. 

根据我的阅读,我需要更改一下我的Rails应用程序,以便它可以接受来自其他服务器的连接(这看起来很奇怪,因为这两个应用程序都运行在同一个ec2实例上)。

我尝试添加类似

的行
  skip_before_filter :verify_authenticity_token

我的控制器在rails中,但这似乎没有效果。

如何解决此错误?

3 个答案:

答案 0 :(得分:19)

在app / controllers / application_controller.rb中:

before_filter :add_allow_credentials_headers

def add_allow_credentials_headers                                                                                                                                                                                                                                                        
  # https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#section_5                                                                                                                                                                                                      
  #                                                                                                                                                                                                                                                                                       
  # Because we want our front-end to send cookies to allow the API to be authenticated                                                                                                                                                                                                   
  # (using 'withCredentials' in the XMLHttpRequest), we need to add some headers so                                                                                                                                                                                                      
  # the browser will not reject the response                                                                                                                                                                                                                                             
  response.headers['Access-Control-Allow-Origin'] = request.headers['Origin'] || '*'                                                                                                                                                                                                     
  response.headers['Access-Control-Allow-Credentials'] = 'true'                                                                                                                                                                                                                          
end 

def options                                                                                                                                                                                                                                                                              
  head :status => 200, :'Access-Control-Allow-Headers' => 'accept, content-type'                                                                                                                                                                                                         
end

在config / routes.rb中:

match '*any' => 'application#options', :via => [:options]

注意,这是响应OPTIONS请求,如果Angular前端正在执行POST请求,您将需要这些请求。我使用Access-Control-Allow-Credentials进行的操作是针对我的应用程序的,因此cookie是从前端发送的。

我强烈建议您在上面的代码中阅读该mozilla链接中的文档。它对CORS有一个非常彻底的解释。您可能会发现上面的代码对您的目的来说过于宽松。

答案 1 :(得分:1)

如果你还没有读过它,请告诉我一些问题是什么......

您的应用的CORS policy存在问题

-

CORS(Corss Origin资源共享)

当您使用XHR(endpoint)访问另一台服务器上的XML HTTP REQUEST时,您的应用程序(虽然我不确定如何)默认会拒绝访问请求资源。

发生这种情况的原因是为了确保只通过XHR提供某些数据/资源,这就是为什么它主要用于API等。

enter image description here

-

<强>机架CORS

无论如何,您需要允许访问Rails应用程序中的Java应用程序 - 我个人建议使用rack-CORS gem:

#Gemfile
gem 'rack-cors'

#config/application.rb
config.middleware.use Rack::Cors do
   allow do
     origins '*'
     resource 'api/jquery', :headers => :any, :methods => [:get, :post]
   end
end

这将“允许”来自您不同应用程序的请求,为您解决问题。

答案 2 :(得分:0)

尝试使用此代码

  <httpProtocol>
          <customHeaders>
           <add name="Access-Control-Allow-Origin" value="*" />
           <add name="Access-Control-Allow-Headers" value="Content-Type" />
           <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS"/>
          </customHeaders>
     </httpProtocol>

inside the <system.webServer>